/*

This software module was originally developed by 

Luke Dahl, Brian Link (E-mu Systems)


in the course of development of the MPEG-4 Audio (ISO/IEC 14496-3) standard. 
This software module is an implementation of a part of one or more 
MPEG-4 Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio 
(ISO/IEC 14496-3). ISO/IEC gives users of the MPEG-4 Audio (ISO/IEC 14496-3) 
free license to this software module or modifications thereof for use 
in hardware or software products claiming conformance to the MPEG-4 Audio 
(ISO/IEC 14496-3). Those intending to use this software module in hardware 
or software products are advised that its use may infringe existing patents. 
The original developer of this software module and his/her company, the 
subsequent editors and their companies, and ISO/IEC have no liability for 
use of this software module or modifications thereof in an implementation. 
Copyright is not released for non MPEG-4 Audio (ISO/IEC 14496-3) conforming 
products. E-mu Systems retains full right to use the code for his/her own 
purpose, assign or donate the code to a third party and to inhibit third 
parties from using the code for non MPEG-4 Audio (ISO/IEC 14496-3) 
conforming products. This copyright notice must be included in all copies 
or derivative works. 

Copyright (C) 1997 E-mu Systems, Inc.

*/

/*****************************************************************************
;
;	sf_wave_equ.h
;
;	Equates for wavetable simulation
;
*****************************************************************************/


#ifndef SF_WAVE_EQU_H
#define SF_WAVE_EQU_H

#include "sfe_enab.h"

#define BITS		16				/* number of bits in audio samples */
#define	MAXINT		(1 << (BITS - 1))	/* for float to int conversions */

/* FIGURE OUT THIS STUFF BELOW LATER!!! */
#define GMSYNTHMODE		0			/* general midi */
#define GSSYNTHMODE		1			/* general synth */
#define MT32SYNTHMODE	2			/* MT-32 */
#define CUSTOMSYNTHMODE	3			/* full custom */
#define SYNTHMODE		GMSYNTHMODE
#define SYNTHMODEINITSZ	7			/* bytes in sysex msg to init mode */
#define FALSE 0
#define TRUE 1

typedef struct sfStuffTag
{
	sfBankID id;						/* pointers to SF Bank ID numbers */
	double *samples;					/* samples in host memory */
	DWORD sampleSizeInBytes;			/* how much host memory used for samples */
} sfStuff;

typedef enum 						/* envelope states (phases) */
{	
	OFF,
	DELAY,
	ATTACK,
	HOLD,
	DECAY,
	SUSTAIN,
	RELEASE
} EnvStateType;

typedef enum						/* control messages to env_val */
{	
	ENV_NONE, 
	ENV_START, 
	ENV_STOP, 
	ENV_ABORT
} EnvMessageType;

typedef enum						/* samplemode types */
{
	LOOP_NONE,						/* sample does not loop */
	LOOP_CONT,						/* sample always loops */
	LOOP_HOLD
} SampleModeType;


struct Env
{
	EnvStateType state;			/* state (stage) of envelope				*/
	double value;				/* current value							*/
	int count;					/* frame counter							*/
	int delay;					/* delay, in frames							*/
	double attack;				/* attack, linear interp increment			*/
	int hold;					/* hold, in frames							*/
	double decay;				/* decay, multiplier (from time const)		*/
	double sustain;				/* sustain, threshold (from dB level)		*/
	double release;				/* release, multiplier (from time const)	*/
};

struct Lfo
{
	double value;				/* current value							*/
	int count;					/* frame counter							*/
	int delay;					/*											*/
	double freq;				/* frame increment							*/
};

/*#define DEBUGTIME*/

struct SynthParams
{

/*	Oscillator */

	double *Start;				/* start address for sample */
	double *End;				/* end address for sample */
	double *Startloop;			/* start address for loop */
	double *Endloop;			/* end address for loop */

	double *curSamp;			/* current sample pointer */
	double curFract;			/* interpolation value */
	int InitPitch;				/* pitch shift in cents */
	double PhaseInc;			/* update for curfrac, number of samples */
	double PitchEnvToPitch;		/* in cents */
	double Lfo1ToPitch;			/* in cents */
	double Lfo2ToPitch;			/* in cents */
	int SFLfo1ToPitchVal;		/* in cents required for continuous MIDI */
	int SFLfo2ToPitchVal;		/* in cents required for continuous MIDI */

	SampleModeType	SampleMode;

#ifdef DEBUGTIME
	double StartTime;
#endif

/*	Envelopes */

	struct Env VolEnv;
	struct Env PitchEnv;

	EnvMessageType EnvMessage;
	int InstantAttack;			/* TRUE if instantaneous attack */
	int SFVolValue;				/* required for continuous MIDI volume */
	double Vol;					/* sample volume multiplier */
	double VolInc;				/* sample to sample increment of Vol */
	double Attenuation;			/* in cB */
	double Tremolo;				/* in cB */

/*	LFOs */

	struct Lfo Lfo1;
	struct Lfo Lfo2;

/*	Filter */

	double InitFilterFc;
	double FilterFc;
	double FilterFcInc;
	double FilterQ;
	double Lfo1ToFilterFc;
	double PitchEnvToFilterFc;
	double FilterZ1;
	double FilterZ2;

/*	Mixing */

	int SFPanValue;			/* due to bad function partition in EMU8200 */
	double LSend;
	double RSend;
	int SFRvbSendVal;		/* required for delta continusous control */
	int SFChsSendVal;		/* required for delta continusous control */
	double RvbSend;
	double ChsSend;

/*	Midi */

	int Chan;
	int Note;
	int InSustain;			/* TRUE if NOTE OFF but sustain pedal TRUE */
	int Pending;
};

/*	Filter Coefficient Table for 4-Tap Interpolator */
/*	 There are 32 table entries for each filter tap. The whole table */
/*	 is present. The symmetry has not been exploited.				 */

/*   NOTE: this filter is now modified. The leading zero was moe to the */
/*   end. This way a1 hits the max for frac=0.							*/

#define G05NEW_FilterOrder 4
#define G05NEW_EntryPerTap 32
#define G05NEW_TableLength (G05NEW_FilterOrder * G05NEW_EntryPerTap)
/*	Prototype filter table for the "new" G0.5 4-point interpolator */

#ifdef PREINTERPOLATE
/* This is for the pre-interpolation of the table. PREINTER_EntryPerTap 	*/
/* is how many entries are desired for each tap. init_interp_table()    	*/
/* will linearly interpoate the prototype table to achieve the correct   	*/
/* number of entries and leave them in PREINTERCoefTab[]. It is probably 	*/
/* true that PREINTER_EntryPerTap must be an integer multiple of 		*/
/* G05NEW_EntryPerTap.								*/

#define PREINTER_EntryPerTap (G05NEW_EntryPerTap * 8)   /* Upsample by 8 */ 
#define PREINTER_Ratio (PREINTER_EntryPerTap / G05NEW_EntryPerTap)
#define PREINTER_Fraction ((float) G05NEW_EntryPerTap / PREINTER_EntryPerTap)
#define PREINTER_TableLength (G05NEW_FilterOrder * PREINTER_EntryPerTap)

double PREINTERCoefTab[PREINTER_TableLength];

#endif /*PREINTERPOLATE */
extern double g05new4tap[];

#endif /* SF_WAVE_EQU_H */
