summaryrefslogtreecommitdiffstats
path: root/arm-wt-22k/lib_src/eas_synth.h
blob: 6274b7db5a513a7bbf9ff9f237f009a6ebed7439 (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 */