C++程序  |  396行  |  11.34 KB

/*----------------------------------------------------------------------------
 *
 * File: 
 * eas_synth.h
 *
 * Contents and purpose:
 * Declarations, interfaces, and prototypes for synth.
 *			
 * Copyright Sonic Network Inc. 2004, 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: 718 $
 *   $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
 *----------------------------------------------------------------------------
*/

#ifndef _EAS_SYNTH_H
#define _EAS_SYNTH_H

#include "eas_types.h"
#include "eas_sndlib.h"

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

#ifdef _FM_SYNTH
#include "eas_fmsynth.h"
#endif

#ifndef NUM_OUTPUT_CHANNELS
#define NUM_OUTPUT_CHANNELS 		2
#endif

#ifndef MAX_SYNTH_VOICES
#define MAX_SYNTH_VOICES			64
#endif

#ifndef MAX_VIRTUAL_SYNTHESIZERS
#define MAX_VIRTUAL_SYNTHESIZERS	4
#endif

/* defines */
#ifndef NUM_PRIMARY_VOICES
#define NUM_PRIMARY_VOICES		MAX_SYNTH_VOICES
#elif !defined(NUM_SECONDARY_VOICES)
#define NUM_SECONDARY_VOICES	(MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES) 
#endif

#if defined(EAS_WT_SYNTH)
#define NUM_WT_VOICES			MAX_SYNTH_VOICES

/* FM on MCU */
#elif defined(EAS_FM_SYNTH)
#define NUM_FM_VOICES			MAX_SYNTH_VOICES

/* wavetable drums on MCU, wavetable melodic on DSP */
#elif defined(EAS_SPLIT_WT_SYNTH)
#define NUM_WT_VOICES			MAX_SYNTH_VOICES

/* wavetable drums and FM melodic on MCU */
#elif defined(EAS_HYBRID_SYNTH)
#define NUM_WT_VOICES			NUM_PRIMARY_VOICES
#define NUM_FM_VOICES			NUM_SECONDARY_VOICES

/* wavetable drums on MCU, FM melodic on DSP */
#elif defined(EAS_SPLIT_HYBRID_SYNTH)
#define NUM_WT_VOICES			NUM_PRIMARY_VOICES
#define NUM_FM_VOICES			NUM_SECONDARY_VOICES

/* FM synth on DSP */
#elif defined(EAS_SPLIT_FM_SYNTH)
#define NUM_FM_VOICES			MAX_SYNTH_VOICES

#else
#error "Unrecognized architecture option"
#endif

#define NUM_SYNTH_CHANNELS		16

#define DEFAULT_SYNTH_VOICES	MAX_SYNTH_VOICES

/* use the following values to specify unassigned channels or voices */
#define UNASSIGNED_SYNTH_CHANNEL	NUM_SYNTH_CHANNELS
#define UNASSIGNED_SYNTH_VOICE		MAX_SYNTH_VOICES


/* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
#define SYNTH_UPDATE_PERIOD_IN_SAMPLES	(EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)

/* stealing weighting factors */
#define NOTE_AGE_STEAL_WEIGHT			1
#define NOTE_GAIN_STEAL_WEIGHT			4
#define CHANNEL_POLY_STEAL_WEIGHT		12
#define CHANNEL_PRIORITY_STEAL_WEIGHT	2
#define NOTE_MATCH_PENALTY				128
#define SYNTH_PRIORITY_WEIGHT			8

/* default synth master volume */
#define DEFAULT_SYNTH_MASTER_VOLUME		0x7fff

#define DEFAULT_SYNTH_PRIORITY			5

/* default tuning values */
#define DEFAULT_PITCH_BEND_SENSITIVITY		200		/* 2 semitones */
#define DEFAULT_FINE_PITCH					0		/* 0 cents */
#define DEFAULT_COARSE_PITCH				0		/* 0 semitones */

/* default drum channel is 10, but is internally 9 due to unit offset */
#define DEFAULT_DRUM_CHANNEL			9

/* drum channel can simultaneously play this many voices at most */
#define DEFAULT_CHANNEL_POLYPHONY_LIMIT	2

/* default instrument is acoustic piano */
#define DEFAULT_MELODY_BANK_MSB			0x79
#define DEFAULT_RHYTHM_BANK_MSB			0x78
#define DEFAULT_MELODY_BANK_NUMBER		(DEFAULT_MELODY_BANK_MSB << 8)
#define DEFAULT_RHYTHM_BANK_NUMBER		(DEFAULT_RHYTHM_BANK_MSB << 8)
#define DEFAULT_SYNTH_PROGRAM_NUMBER	0

#define DEFAULT_PITCH_BEND		0x2000	/* 0x2000 == (0x40 << 7) | 0x00 */
#define DEFAULT_MOD_WHEEL		0
#define DEFAULT_CHANNEL_VOLUME	0x64
#define DEFAULT_PAN				0x40	/* decimal 64, center */

#ifdef _REVERB
#define DEFAULT_REVERB_SEND		40		/* some reverb */
#endif

#ifdef _CHORUS
#define DEFAULT_CHORUS_SEND		0		/* no chorus */
#endif

#define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY	0			/* EAS synth uses a different default */
#define DEFAULT_FILTER_RESONANCE		0
#define DEFAULT_EXPRESSION				0x7F

#define DEFAULT_CHANNEL_PRESSURE		0

#define DEFAULT_REGISTERED_PARAM		0x3FFF

#define DEFAULT_CHANNEL_STATIC_GAIN		0
#define DEFAULT_CHANNEL_STATIC_PITCH	0

#define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS			50
#define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS		50	
													
#define DEFAULT_KEY_NUMBER			0x69
#define DEFAULT_VELOCITY			0x64
#define DEFAULT_REGION_INDEX		0
#define DEFAULT_ARTICULATION_INDEX	0
#define DEFAULT_VOICE_GAIN			0
#define DEFAULT_AGE					0
#define DEFAULT_SP_MIDI_PRIORITY	16


/* filter defines */
#define DEFAULT_FILTER_ZERO		0
#define FILTER_CUTOFF_MAX_PITCH_CENTS		1919
#define FILTER_CUTOFF_MIN_PITCH_CENTS		-4467
#define A5_PITCH_OFFSET_IN_CENTS			6900

/*------------------------------------
 * S_SYNTH_CHANNEL data structure
 *------------------------------------
*/

/* S_SYNTH_CHANNEL.m_nFlags */
#define CHANNEL_FLAG_SUSTAIN_PEDAL						0x01
#define CHANNEL_FLAG_MUTE								0x02
#define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS			0x04
#define CHANNEL_FLAG_RHYTHM_CHANNEL						0x08
#define CHANNEL_FLAG_EXTERNAL_AUDIO						0x10
#define DEFAULT_CHANNEL_FLAGS							0

/* macros for extracting virtual synth and channel numbers */
#define GET_VSYNTH(a) ((a) >> 4)
#define GET_CHANNEL(a) ((a) & 15)

typedef struct s_synth_channel_tag
{
	/* use static channel parameters to reduce MIPs */
	/* parameters shared by multiple voices assigned to same channel */
	EAS_I32		staticPitch;		/* (pitch bend * pitch sens) + fine pitch */
	EAS_I16		staticGain;			/* (CC7 * CC11 * master vol)^2	*/

	EAS_U16		regionIndex;		/* index of first region in program */
	
	EAS_U16		bankNum;			/* play programs from this bank */
	EAS_I16		pitchBend;			/* pitch wheel value */
	EAS_I16		pitchBendSensitivity;
	EAS_I16		registeredParam;	/* currently selected registered param */


#if defined(_FM_SYNTH)
	EAS_I16		lfoAmt;				/* amount of LFO to apply to voice */
#endif    
	
	EAS_U8		programNum;			/* play this instrument number */
	EAS_U8		modWheel;			/* CC1 */
	EAS_U8		volume;				/* CC7 */
	EAS_U8		pan;				/* CC10 */

	EAS_U8		expression;			/* CC11 */

	/* the following parameters are controlled by RPNs */
	EAS_I8		finePitch;
	EAS_I8		coarsePitch;

	EAS_U8		channelPressure;	/* applied to all voices on a given channel */

	EAS_U8		channelFlags;		/* bit field channelFlags for */
									/* CC64, SP-MIDI channel masking */	

	EAS_U8		pool;				/* SPMIDI channel voice pool */
	EAS_U8		mip;				/* SPMIDI MIP setting */
	
#ifdef	_REVERB
	EAS_U8		reverbSend;			/* CC91 */
#endif

#ifdef	_CHORUS
	EAS_U8		chorusSend;			/* CC93 */
#endif
} S_SYNTH_CHANNEL;

/*------------------------------------
 * S_SYNTH_VOICE data structure
 *------------------------------------
*/

/* S_SYNTH_VOICE.m_nFlags */
#define	VOICE_FLAG_UPDATE_VOICE_PARAMETERS				0x01
#define	VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF			0x02
#define	VOICE_FLAG_DEFER_MIDI_NOTE_OFF					0x04
#define	VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET			0x08
#define	VOICE_FLAG_DEFER_MUTE							0x40
#define	DEFAULT_VOICE_FLAGS								0

/* S_SYNTH_VOICE.m_eState */
typedef enum {

	eVoiceStateFree = 0,
	eVoiceStateStart,
	eVoiceStatePlay,
	eVoiceStateRelease,
	eVoiceStateMuting,
	eVoiceStateStolen,
	eVoiceStateInvalid			/* should never be in this state! */

} E_VOICE_STATE;
#define DEFAULT_VOICE_STATE		eVoiceStateFree

typedef struct s_synth_voice_tag
{

/* These parameters are common to both wavetable and FM
 * synthesizers. The voice manager should only access this data.
 * Any other data should be manipulated by the code that is
 * specific to that synthesizer and reflected back through the
 * common state data available here.
 */
	EAS_U16				regionIndex;		/* index to wave and playback params */
	EAS_I16				gain;				/* current gain */
	EAS_U16				age;				/* large value means old note */
	EAS_U16				nextRegionIndex;	/* index to wave and playback params */
	EAS_U8				voiceState;			/* current voice state */
	EAS_U8				voiceFlags;			/* misc flags/bit fields */
	EAS_U8				channel;			/* this voice plays on this synth channel */
	EAS_U8				note;				/* 12 <= key number <= 108 */
	EAS_U8				velocity;			/* 0 <= velocity <= 127 */
	EAS_U8				nextChannel;		/* play stolen voice on this channel */
	EAS_U8				nextNote;			/* 12 <= key number <= 108 */
	EAS_U8				nextVelocity;		/* 0 <= velocity <= 127 */
} S_SYNTH_VOICE;

/*------------------------------------
 * S_SYNTH data structure
 *
 * One instance for each MIDI stream
 *------------------------------------
*/

/* S_SYNTH.m_nFlags */
#define	SYNTH_FLAG_RESET_IS_REQUESTED					0x01
#define	SYNTH_FLAG_SP_MIDI_ON							0x02
#define	SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS		0x04
#define	SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING		0x08
#define	DEFAULT_SYNTH_FLAGS 	SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS

typedef struct s_synth_tag
{
	struct s_eas_data_tag	*pEASData;
	const S_EAS				*pEAS;

#ifdef DLS_SYNTHESIZER	
	S_DLS					*pDLS;
#endif

#ifdef EXTERNAL_AUDIO
	EAS_EXT_PRG_CHG_FUNC 	cbProgChgFunc;
	EAS_EXT_EVENT_FUNC 		cbEventFunc;
	EAS_VOID_PTR			*pExtAudioInstData;
#endif
	
	S_SYNTH_CHANNEL			channels[NUM_SYNTH_CHANNELS];
	EAS_I32					totalNoteCount;
	EAS_U16					maxPolyphony;
	EAS_U16					numActiveVoices;
	EAS_U16					masterVolume;
	EAS_U8					channelsByPriority[NUM_SYNTH_CHANNELS];
	EAS_U8					poolCount[NUM_SYNTH_CHANNELS];
	EAS_U8					poolAlloc[NUM_SYNTH_CHANNELS];
	EAS_U8					synthFlags;
	EAS_I8					globalTranspose;
	EAS_U8					vSynthNum;
	EAS_U8					refCount;
	EAS_U8					priority;
} S_SYNTH;

/*------------------------------------
 * S_VOICE_MGR data structure
 *
 * One instance for each EAS library instance
 *------------------------------------
*/
typedef struct s_voice_mgr_tag
{
	S_SYNTH					*pSynth[MAX_VIRTUAL_SYNTHESIZERS];
	EAS_PCM					voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];

#ifdef _FM_SYNTH
	EAS_PCM					operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
	S_FM_VOICE				fmVoices[NUM_FM_VOICES];
#endif

#ifdef _WT_SYNTH
	S_WT_VOICE				wtVoices[NUM_WT_VOICES];
#endif

#ifdef _REVERB
	EAS_PCM					reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
#endif

#ifdef _CHORUS
	EAS_PCM					chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
#endif
	S_SYNTH_VOICE			voices[MAX_SYNTH_VOICES];

	EAS_SNDLIB_HANDLE		pGlobalEAS;

#ifdef DLS_SYNTHESIZER	
	S_DLS					*pGlobalDLS;
#endif

#ifdef _SPLIT_ARCHITECTURE
	EAS_FRAME_BUFFER_HANDLE	pFrameBuffer;
#endif

#if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
	EAS_U16					maxPolyphonyPrimary;
	EAS_U16					maxPolyphonySecondary;
#endif

	EAS_I32					workload;
	EAS_I32					maxWorkLoad;

	EAS_U16					activeVoices;
	EAS_U16					maxPolyphony;

	EAS_U16					age;

/* limits the number of voice starts in a frame for split architecture */
#ifdef MAX_VOICE_STARTS
	EAS_U16					numVoiceStarts;
#endif
} S_VOICE_MGR;

#endif /* #ifdef _EAS_SYNTH_H */