/*----------------------------------------------------------------------------
 *
 * File: 
 * eas_sndlib.h
 *
 * Contents and purpose:
 * Declarations for the sound library 
 *			
 * Copyright Sonic Network Inc. 2005

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *----------------------------------------------------------------------------
 * Revision Control:
 *   $Revision: 550 $
 *   $Date: 2007-02-02 09:37:03 -0800 (Fri, 02 Feb 2007) $
 *----------------------------------------------------------------------------
*/

#ifndef _EAS_SNDLIB_H
#define _EAS_SNDLIB_H

#include "eas_types.h"
#include "eas_synthcfg.h"

#ifdef _WT_SYNTH
#include "eas_wtengine.h"
#endif

/*----------------------------------------------------------------------------
 * This is bit of a hack to allow us to keep the same structure
 * declarations for the DLS parser. Normally, the data is located
 * in read-only memory, but for DLS, we store the data in RW
 * memory.
 *----------------------------------------------------------------------------
*/
#ifndef SCNST
#define SCNST const
#endif

/*----------------------------------------------------------------------------
 * sample size
 *----------------------------------------------------------------------------
*/
#ifdef _16_BIT_SAMPLES
typedef EAS_I16 EAS_SAMPLE;
#else
typedef EAS_I8 EAS_SAMPLE;
#endif

/*----------------------------------------------------------------------------
 * EAS Library ID - quick check for valid library and version
 *----------------------------------------------------------------------------
*/
#define _EAS_LIBRARY_VERSION		0x01534145

#define NUM_PROGRAMS_IN_BANK		128
#define INVALID_REGION_INDEX		0xffff

/* this bit in region index indicates that region is for secondary synth */
#define FLAG_RGN_IDX_FM_SYNTH 		0x8000
#define FLAG_RGN_IDX_DLS_SYNTH 		0x4000
#define REGION_INDEX_MASK			0x3fff

/*----------------------------------------------------------------------------
 * Generic region data structure
 *
 * This must be the first element in each region structure
 *----------------------------------------------------------------------------
*/
typedef struct s_region_tag
{
	EAS_U16		keyGroupAndFlags;
	EAS_U8		rangeLow;
	EAS_U8		rangeHigh;
} S_REGION;

/*
 * Bit fields for m_nKeyGroupAndFlags
 * Bits 0-2 are mode bits in FM synth
 * Bits 8-11 are the key group
 */
#define REGION_FLAG_IS_LOOPED					0x01
#define REGION_FLAG_USE_WAVE_GENERATOR			0x02
#define REGION_FLAG_USE_ADPCM					0x04
#define REGION_FLAG_ONE_SHOT					0x08
#define REGION_FLAG_SQUARE_WAVE					0x10
#define REGION_FLAG_OFF_CHIP					0x20
#define REGION_FLAG_NON_SELF_EXCLUSIVE			0x40
#define REGION_FLAG_LAST_REGION					0x8000

/*----------------------------------------------------------------------------
 * Envelope data structure
 *----------------------------------------------------------------------------
*/
typedef struct s_envelope_tag
{
	EAS_I16		attackTime;
	EAS_I16		decayTime;
	EAS_I16		sustainLevel;
	EAS_I16		releaseTime;
} S_ENVELOPE;

/*----------------------------------------------------------------------------
 * DLS envelope data structure
 *----------------------------------------------------------------------------
*/
typedef struct s_dls_envelope_tag
{
	EAS_I16			delayTime;
	EAS_I16			attackTime;
	EAS_I16			holdTime;
	EAS_I16			decayTime;
	EAS_I16			sustainLevel;
	EAS_I16			releaseTime;
	EAS_I16			velToAttack;
	EAS_I16			keyNumToDecay;
	EAS_I16			keyNumToHold;
} S_DLS_ENVELOPE;

/*----------------------------------------------------------------------------
 * LFO data structure
 *----------------------------------------------------------------------------
*/
typedef struct s_lfo_params_tag
{
	EAS_I16		lfoFreq;
	EAS_I16		lfoDelay;
} S_LFO_PARAMS;

/*----------------------------------------------------------------------------
 * Articulation data structure
 *----------------------------------------------------------------------------
*/
typedef struct s_articulation_tag
{
	S_ENVELOPE	eg1;
	S_ENVELOPE	eg2;
	EAS_I16		lfoToPitch;
	EAS_I16		lfoDelay;
	EAS_I16		lfoFreq;
	EAS_I16		eg2ToPitch;
	EAS_I16		eg2ToFc;
	EAS_I16		filterCutoff;
	EAS_I8		lfoToGain;
	EAS_U8		filterQ;
	EAS_I8		pan;
} S_ARTICULATION;

/*----------------------------------------------------------------------------
 * DLS articulation data structure
 *----------------------------------------------------------------------------
*/

typedef struct s_dls_articulation_tag
{
	S_LFO_PARAMS	modLFO;
	S_LFO_PARAMS	vibLFO;

	S_DLS_ENVELOPE	eg1;
	S_DLS_ENVELOPE	eg2;
	
	EAS_I16			eg1ShutdownTime;

	EAS_I16			filterCutoff;
	EAS_I16			modLFOToFc;
	EAS_I16			modLFOCC1ToFc;
	EAS_I16			modLFOChanPressToFc;
	EAS_I16			eg2ToFc;
	EAS_I16			velToFc;
	EAS_I16			keyNumToFc;

	EAS_I16			modLFOToGain;
	EAS_I16			modLFOCC1ToGain;
	EAS_I16			modLFOChanPressToGain;

	EAS_I16			tuning;
	EAS_I16			keyNumToPitch;
	EAS_I16			vibLFOToPitch;
	EAS_I16			vibLFOCC1ToPitch;
	EAS_I16			vibLFOChanPressToPitch;
	EAS_I16			modLFOToPitch;
	EAS_I16			modLFOCC1ToPitch;
	EAS_I16			modLFOChanPressToPitch;
	EAS_I16			eg2ToPitch;

	/* pad to 4-byte boundary */
	EAS_U16			pad;
	
	EAS_I8			pan;
	EAS_U8			filterQandFlags;

#ifdef _REVERB	
	EAS_I16			reverbSend;
	EAS_I16			cc91ToReverbSend;
#endif

#ifdef _CHORUS
	EAS_I16			chorusSend;
	EAS_I16			cc93ToChorusSend;
#endif	
} S_DLS_ARTICULATION;

/* flags in filterQandFlags
 * NOTE: Q is stored in bottom 5 bits
 */
#define FLAG_DLS_VELOCITY_SENSITIVE		0x80
#define FILTER_Q_MASK					0x1f

/*----------------------------------------------------------------------------
 * Wavetable region data structure
 *----------------------------------------------------------------------------
*/
typedef struct s_wt_region_tag
{
	S_REGION	region;
	EAS_I16		tuning;
	EAS_I16		gain;
	EAS_U32		loopStart;
	EAS_U32		loopEnd;
	EAS_U16		waveIndex;
	EAS_U16		artIndex;
} S_WT_REGION;

/*----------------------------------------------------------------------------
 * DLS region data structure
 *----------------------------------------------------------------------------
*/
typedef struct s_dls_region_tag
{
	S_WT_REGION		wtRegion;
	EAS_U8			velLow;
	EAS_U8			velHigh;
} S_DLS_REGION;

/*----------------------------------------------------------------------------
 * FM synthesizer data structures
 *----------------------------------------------------------------------------
*/
typedef struct s_fm_oper_tag
{
	EAS_I16		tuning;
	EAS_U8		attackDecay;
	EAS_U8		velocityRelease;
	EAS_U8		egKeyScale;
	EAS_U8		sustain;
	EAS_U8		gain;
	EAS_U8		flags;
} S_FM_OPER;

/* defines for S_FM_OPER.m_nFlags */
#define FM_OPER_FLAG_MONOTONE			0x01
#define FM_OPER_FLAG_NO_VIBRATO			0x02
#define FM_OPER_FLAG_NOISE				0x04
#define FM_OPER_FLAG_LINEAR_VELOCITY	0x08

/* NOTE: The first two structure elements are common with S_WT_REGION
 * and we will rely on that in the voice management code and must
 * remain there unless the voice management code is revisited.
 */
typedef struct s_fm_region_tag
{
	S_REGION		region;
	EAS_U8			vibTrem;
	EAS_U8			lfoFreqDelay;
	EAS_U8			feedback;
	EAS_I8			pan;
	S_FM_OPER 		oper[4];
} S_FM_REGION;

/*----------------------------------------------------------------------------
 * Common data structures
 *----------------------------------------------------------------------------
*/

/*----------------------------------------------------------------------------
 * Program data structure
 * Used for individual programs not stored as a complete bank.
 *----------------------------------------------------------------------------
*/
typedef struct s_program_tag
{
	EAS_U32	locale;
	EAS_U16	regionIndex;
} S_PROGRAM;

/*----------------------------------------------------------------------------
 * Bank data structure
 *
 * A bank always consists of 128 programs. If a bank is less than 128
 * programs, it should be stored as a spare matrix in the pPrograms
 * array.
 *
 * bankNum:		MSB/LSB of MIDI bank select controller
 * regionIndex:	Index of first region in program
 *----------------------------------------------------------------------------
*/
typedef struct s_bank_tag
{
	EAS_U16	locale;
	EAS_U16	regionIndex[NUM_PROGRAMS_IN_BANK];
} S_BANK;


/* defines for libFormat field
 * bits 0-17 are the sample rate
 * bit 18 is true if wavetable is present
 * bit 19 is true if FM is present
 * bit 20 is true if filter is enabled
 * bit 21 is sample depth (0 = 8-bits, 1 = 16-bits)
 * bits 22-31 are reserved
 */
#define LIBFORMAT_SAMPLE_RATE_MASK 		0x0003ffff
#define LIB_FORMAT_TYPE_MASK			0x000c0000
#define LIB_FORMAT_WAVETABLE			0x00000000
#define LIB_FORMAT_FM					0x00040000
#define LIB_FORMAT_HYBRID				0x00080000
#define LIB_FORMAT_FILTER_ENABLED		0x00100000
#define LIB_FORMAT_16_BIT_SAMPLES		0x00200000

#ifdef DLS_SYNTHESIZER
/*----------------------------------------------------------------------------
 * DLS data structure
 *
 * pDLSPrograms			pointer to array of DLS programs
 * pDLSRegions			pointer to array of DLS regions
 * pDLSArticulations	pointer to array of DLS articulations
 * pSampleLen			pointer to array of sample lengths
 * ppSamples			pointer to array of sample pointers
 * numDLSPrograms		number of DLS programs
 * numDLSRegions		number of DLS regions
 * numDLSArticulations	number of DLS articulations
 * numDLSSamples		number of DLS samples
 *----------------------------------------------------------------------------
*/
typedef struct s_eas_dls_tag
{
	S_PROGRAM			*pDLSPrograms;
	S_DLS_REGION		*pDLSRegions;
	S_DLS_ARTICULATION	*pDLSArticulations;
	EAS_U32				*pDLSSampleLen;
	EAS_U32				*pDLSSampleOffsets;
	EAS_SAMPLE			*pDLSSamples;
	EAS_U16				numDLSPrograms;
	EAS_U16				numDLSRegions;
	EAS_U16				numDLSArticulations;	
	EAS_U16				numDLSSamples;
	EAS_U8				refCount;
} S_DLS;	
#endif

/*----------------------------------------------------------------------------
 * Sound library data structure
 *
 * pBanks			pointer to array of banks
 * pPrograms		pointer to array of programs
 * pWTRegions		pointer to array of wavetable regions
 * pFMRegions		pointer to array of FM regions
 * pArticulations	pointer to array of articulations
 * pSampleLen		pointer to array of sample lengths
 * ppSamples		pointer to array of sample pointers
 * numBanks			number of banks
 * numPrograms		number of individual program
 * numRegions		number of regions
 * numArticulations	number of articulations
 * numSamples		number of samples
 *----------------------------------------------------------------------------
*/
typedef struct s_eas_sndlib_tag
{
	SCNST EAS_U32				identifier;
	SCNST EAS_U32				libAttr;

	SCNST S_BANK				*pBanks;
	SCNST S_PROGRAM				*pPrograms;
	
	SCNST S_WT_REGION			*pWTRegions;
	SCNST S_ARTICULATION		*pArticulations;
	SCNST EAS_U32				*pSampleLen;
	SCNST EAS_U32				*pSampleOffsets;
	SCNST EAS_SAMPLE			*pSamples;

	SCNST S_FM_REGION			*pFMRegions;

	SCNST EAS_U16				numBanks;
	SCNST EAS_U16				numPrograms;

	SCNST EAS_U16				numWTRegions;
	SCNST EAS_U16				numArticulations;	
	SCNST EAS_U16				numSamples;
	
	SCNST EAS_U16				numFMRegions;
} S_EAS;

#endif