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 */
|