summaryrefslogtreecommitdiffstats
path: root/arm-fm-22k/lib_src/eas_synth.h
blob: b242b03edc9045b50659ac18ac5aa301664ae1d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/*----------------------------------------------------------------------------
 *
 * 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 */