1 /*----------------------------------------------------------------------------
2  *
3  * File:
4  * eas_synth.h
5  *
6  * Contents and purpose:
7  * Declarations, interfaces, and prototypes for synth.
8  *
9  * Copyright Sonic Network Inc. 2004, 2005
10 
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  *----------------------------------------------------------------------------
24  * Revision Control:
25  *   $Revision: 718 $
26  *   $Date: 2007-06-08 16:43:16 -0700 (Fri, 08 Jun 2007) $
27  *----------------------------------------------------------------------------
28 */
29 
30 #ifndef _EAS_SYNTH_H
31 #define _EAS_SYNTH_H
32 
33 #include "eas_types.h"
34 #include "eas_sndlib.h"
35 
36 #ifdef _WT_SYNTH
37 #include "eas_wtsynth.h"
38 #endif
39 
40 #ifdef _FM_SYNTH
41 #include "eas_fmsynth.h"
42 #endif
43 
44 #ifndef NUM_OUTPUT_CHANNELS
45 #define NUM_OUTPUT_CHANNELS         2
46 #endif
47 
48 #ifndef MAX_SYNTH_VOICES
49 #define MAX_SYNTH_VOICES            64
50 #endif
51 
52 #ifndef MAX_VIRTUAL_SYNTHESIZERS
53 #define MAX_VIRTUAL_SYNTHESIZERS    4
54 #endif
55 
56 /* defines */
57 #ifndef NUM_PRIMARY_VOICES
58 #define NUM_PRIMARY_VOICES      MAX_SYNTH_VOICES
59 #elif !defined(NUM_SECONDARY_VOICES)
60 #define NUM_SECONDARY_VOICES    (MAX_SYNTH_VOICES - NUM_PRIMARY_VOICES)
61 #endif
62 
63 #if defined(EAS_WT_SYNTH)
64 #define NUM_WT_VOICES           MAX_SYNTH_VOICES
65 
66 /* FM on MCU */
67 #elif defined(EAS_FM_SYNTH)
68 #define NUM_FM_VOICES           MAX_SYNTH_VOICES
69 
70 /* wavetable drums on MCU, wavetable melodic on DSP */
71 #elif defined(EAS_SPLIT_WT_SYNTH)
72 #define NUM_WT_VOICES           MAX_SYNTH_VOICES
73 
74 /* wavetable drums and FM melodic on MCU */
75 #elif defined(EAS_HYBRID_SYNTH)
76 #define NUM_WT_VOICES           NUM_PRIMARY_VOICES
77 #define NUM_FM_VOICES           NUM_SECONDARY_VOICES
78 
79 /* wavetable drums on MCU, FM melodic on DSP */
80 #elif defined(EAS_SPLIT_HYBRID_SYNTH)
81 #define NUM_WT_VOICES           NUM_PRIMARY_VOICES
82 #define NUM_FM_VOICES           NUM_SECONDARY_VOICES
83 
84 /* FM synth on DSP */
85 #elif defined(EAS_SPLIT_FM_SYNTH)
86 #define NUM_FM_VOICES           MAX_SYNTH_VOICES
87 
88 #else
89 #error "Unrecognized architecture option"
90 #endif
91 
92 #define NUM_SYNTH_CHANNELS      16
93 
94 #define DEFAULT_SYNTH_VOICES    MAX_SYNTH_VOICES
95 
96 /* use the following values to specify unassigned channels or voices */
97 #define UNASSIGNED_SYNTH_CHANNEL    NUM_SYNTH_CHANNELS
98 #define UNASSIGNED_SYNTH_VOICE      MAX_SYNTH_VOICES
99 
100 
101 /* synth parameters are updated every SYNTH_UPDATE_PERIOD_IN_SAMPLES */
102 #define SYNTH_UPDATE_PERIOD_IN_SAMPLES  (EAS_I32)(0x1L << SYNTH_UPDATE_PERIOD_IN_BITS)
103 
104 /* stealing weighting factors */
105 #define NOTE_AGE_STEAL_WEIGHT           1
106 #define NOTE_GAIN_STEAL_WEIGHT          4
107 #define CHANNEL_POLY_STEAL_WEIGHT       12
108 #define CHANNEL_PRIORITY_STEAL_WEIGHT   2
109 #define NOTE_MATCH_PENALTY              128
110 #define SYNTH_PRIORITY_WEIGHT           8
111 
112 /* default synth master volume */
113 #define DEFAULT_SYNTH_MASTER_VOLUME     0x7fff
114 
115 #define DEFAULT_SYNTH_PRIORITY          5
116 
117 /* default tuning values */
118 #define DEFAULT_PITCH_BEND_SENSITIVITY      200     /* 2 semitones */
119 #define DEFAULT_FINE_PITCH                  0       /* 0 cents */
120 #define DEFAULT_COARSE_PITCH                0       /* 0 semitones */
121 
122 /* default drum channel is 10, but is internally 9 due to unit offset */
123 #define DEFAULT_DRUM_CHANNEL            9
124 
125 /* drum channel can simultaneously play this many voices at most */
126 #define DEFAULT_CHANNEL_POLYPHONY_LIMIT 2
127 
128 /* default instrument is acoustic piano */
129 #define DEFAULT_MELODY_BANK_MSB         0x79
130 #define DEFAULT_RHYTHM_BANK_MSB         0x78
131 #define DEFAULT_MELODY_BANK_NUMBER      (DEFAULT_MELODY_BANK_MSB << 8)
132 #define DEFAULT_RHYTHM_BANK_NUMBER      (DEFAULT_RHYTHM_BANK_MSB << 8)
133 #define DEFAULT_SYNTH_PROGRAM_NUMBER    0
134 
135 #define DEFAULT_PITCH_BEND      0x2000  /* 0x2000 == (0x40 << 7) | 0x00 */
136 #define DEFAULT_MOD_WHEEL       0
137 #define DEFAULT_CHANNEL_VOLUME  0x64
138 #define DEFAULT_PAN             0x40    /* decimal 64, center */
139 
140 #ifdef _REVERB
141 #define DEFAULT_REVERB_SEND     40      /* some reverb */
142 #endif
143 
144 #ifdef _CHORUS
145 #define DEFAULT_CHORUS_SEND     0       /* no chorus */
146 #endif
147 
148 #define DEFAULT_EAS_FILTER_CUTOFF_FREQUENCY 0           /* EAS synth uses a different default */
149 #define DEFAULT_FILTER_RESONANCE        0
150 #define DEFAULT_EXPRESSION              0x7F
151 
152 #define DEFAULT_CHANNEL_PRESSURE        0
153 
154 #define DEFAULT_REGISTERED_PARAM        0x3FFF
155 
156 #define DEFAULT_CHANNEL_STATIC_GAIN     0
157 #define DEFAULT_CHANNEL_STATIC_PITCH    0
158 
159 #define DEFAULT_LFO_MOD_WHEEL_TO_PITCH_CENTS            50
160 #define DEFAULT_LFO_CHANNEL_PRESSURE_TO_PITCH_CENTS     50
161 
162 #define DEFAULT_KEY_NUMBER          0x69
163 #define DEFAULT_VELOCITY            0x64
164 #define DEFAULT_REGION_INDEX        0
165 #define DEFAULT_ARTICULATION_INDEX  0
166 #define DEFAULT_VOICE_GAIN          0
167 #define DEFAULT_AGE                 0
168 #define DEFAULT_SP_MIDI_PRIORITY    16
169 
170 
171 /* filter defines */
172 #define DEFAULT_FILTER_ZERO     0
173 #define FILTER_CUTOFF_MAX_PITCH_CENTS       1919
174 #define FILTER_CUTOFF_MIN_PITCH_CENTS       -4467
175 #define A5_PITCH_OFFSET_IN_CENTS            6900
176 
177 /*------------------------------------
178  * S_SYNTH_CHANNEL data structure
179  *------------------------------------
180 */
181 
182 /* S_SYNTH_CHANNEL.m_nFlags */
183 #define CHANNEL_FLAG_SUSTAIN_PEDAL                      0x01
184 #define CHANNEL_FLAG_MUTE                               0x02
185 #define CHANNEL_FLAG_UPDATE_CHANNEL_PARAMETERS          0x04
186 #define CHANNEL_FLAG_RHYTHM_CHANNEL                     0x08
187 #define CHANNEL_FLAG_EXTERNAL_AUDIO                     0x10
188 #define DEFAULT_CHANNEL_FLAGS                           0
189 
190 /* macros for extracting virtual synth and channel numbers */
191 #define GET_VSYNTH(a) ((a) >> 4)
192 #define GET_CHANNEL(a) ((a) & 15)
193 
194 typedef struct s_synth_channel_tag
195 {
196     /* use static channel parameters to reduce MIPs */
197     /* parameters shared by multiple voices assigned to same channel */
198     EAS_I32     staticPitch;        /* (pitch bend * pitch sens) + fine pitch */
199     EAS_I16     staticGain;         /* (CC7 * CC11 * master vol)^2  */
200 
201     EAS_U16     regionIndex;        /* index of first region in program */
202 
203     EAS_U16     bankNum;            /* play programs from this bank */
204     EAS_I16     pitchBend;          /* pitch wheel value */
205     EAS_I16     pitchBendSensitivity;
206     EAS_I16     registeredParam;    /* currently selected registered param */
207 
208 
209 #if defined(_FM_SYNTH)
210     EAS_I16     lfoAmt;             /* amount of LFO to apply to voice */
211 #endif
212 
213     EAS_U8      programNum;         /* play this instrument number */
214     EAS_U8      modWheel;           /* CC1 */
215     EAS_U8      volume;             /* CC7 */
216     EAS_U8      pan;                /* CC10 */
217 
218     EAS_U8      expression;         /* CC11 */
219 
220     /* the following parameters are controlled by RPNs */
221     EAS_I8      finePitch;
222     EAS_I8      coarsePitch;
223 
224     EAS_U8      channelPressure;    /* applied to all voices on a given channel */
225 
226     EAS_U8      channelFlags;       /* bit field channelFlags for */
227                                     /* CC64, SP-MIDI channel masking */
228 
229     EAS_U8      pool;               /* SPMIDI channel voice pool */
230     EAS_U8      mip;                /* SPMIDI MIP setting */
231 
232 #ifdef  _REVERB
233     EAS_U8      reverbSend;         /* CC91 */
234 #endif
235 
236 #ifdef  _CHORUS
237     EAS_U8      chorusSend;         /* CC93 */
238 #endif
239 } S_SYNTH_CHANNEL;
240 
241 /*------------------------------------
242  * S_SYNTH_VOICE data structure
243  *------------------------------------
244 */
245 
246 /* S_SYNTH_VOICE.m_nFlags */
247 #define VOICE_FLAG_UPDATE_VOICE_PARAMETERS              0x01
248 #define VOICE_FLAG_SUSTAIN_PEDAL_DEFER_NOTE_OFF         0x02
249 #define VOICE_FLAG_DEFER_MIDI_NOTE_OFF                  0x04
250 #define VOICE_FLAG_NO_SAMPLES_SYNTHESIZED_YET           0x08
251 #define VOICE_FLAG_DEFER_MUTE                           0x40
252 #define DEFAULT_VOICE_FLAGS                             0
253 
254 /* S_SYNTH_VOICE.m_eState */
255 typedef enum {
256 
257     eVoiceStateFree = 0,
258     eVoiceStateStart,
259     eVoiceStatePlay,
260     eVoiceStateRelease,
261     eVoiceStateMuting,
262     eVoiceStateStolen,
263     eVoiceStateInvalid          /* should never be in this state! */
264 
265 } E_VOICE_STATE;
266 #define DEFAULT_VOICE_STATE     eVoiceStateFree
267 
268 typedef struct s_synth_voice_tag
269 {
270 
271 /* These parameters are common to both wavetable and FM
272  * synthesizers. The voice manager should only access this data.
273  * Any other data should be manipulated by the code that is
274  * specific to that synthesizer and reflected back through the
275  * common state data available here.
276  */
277     EAS_U16             regionIndex;        /* index to wave and playback params */
278     EAS_I16             gain;               /* current gain */
279     EAS_U16             age;                /* large value means old note */
280     EAS_U16             nextRegionIndex;    /* index to wave and playback params */
281     EAS_U8              voiceState;         /* current voice state */
282     EAS_U8              voiceFlags;         /* misc flags/bit fields */
283     EAS_U8              channel;            /* this voice plays on this synth channel */
284     EAS_U8              note;               /* 12 <= key number <= 108 */
285     EAS_U8              velocity;           /* 0 <= velocity <= 127 */
286     EAS_U8              nextChannel;        /* play stolen voice on this channel */
287     EAS_U8              nextNote;           /* 12 <= key number <= 108 */
288     EAS_U8              nextVelocity;       /* 0 <= velocity <= 127 */
289 } S_SYNTH_VOICE;
290 
291 /*------------------------------------
292  * S_SYNTH data structure
293  *
294  * One instance for each MIDI stream
295  *------------------------------------
296 */
297 
298 /* S_SYNTH.m_nFlags */
299 #define SYNTH_FLAG_RESET_IS_REQUESTED                   0x01
300 #define SYNTH_FLAG_SP_MIDI_ON                           0x02
301 #define SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS        0x04
302 #define SYNTH_FLAG_DEFERRED_MIDI_NOTE_OFF_PENDING       0x08
303 #define DEFAULT_SYNTH_FLAGS     SYNTH_FLAG_UPDATE_ALL_CHANNEL_PARAMETERS
304 
305 typedef struct s_synth_tag
306 {
307     struct s_eas_data_tag   *pEASData;
308     const S_EAS             *pEAS;
309 
310 #ifdef DLS_SYNTHESIZER
311     S_DLS                   *pDLS;
312 #endif
313 
314 #ifdef EXTERNAL_AUDIO
315     EAS_EXT_PRG_CHG_FUNC    cbProgChgFunc;
316     EAS_EXT_EVENT_FUNC      cbEventFunc;
317     EAS_VOID_PTR            *pExtAudioInstData;
318 #endif
319 
320     S_SYNTH_CHANNEL         channels[NUM_SYNTH_CHANNELS];
321     EAS_I32                 totalNoteCount;
322     EAS_U16                 maxPolyphony;
323     EAS_U16                 numActiveVoices;
324     EAS_U16                 masterVolume;
325     EAS_U8                  channelsByPriority[NUM_SYNTH_CHANNELS];
326     EAS_U8                  poolCount[NUM_SYNTH_CHANNELS];
327     EAS_U8                  poolAlloc[NUM_SYNTH_CHANNELS];
328     EAS_U8                  synthFlags;
329     EAS_I8                  globalTranspose;
330     EAS_U8                  vSynthNum;
331     EAS_U8                  refCount;
332     EAS_U8                  priority;
333 } S_SYNTH;
334 
335 /*------------------------------------
336  * S_VOICE_MGR data structure
337  *
338  * One instance for each EAS library instance
339  *------------------------------------
340 */
341 typedef struct s_voice_mgr_tag
342 {
343     S_SYNTH                 *pSynth[MAX_VIRTUAL_SYNTHESIZERS];
344     EAS_PCM                 voiceBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
345 
346 #ifdef _FM_SYNTH
347     EAS_PCM                 operMixBuffer[SYNTH_UPDATE_PERIOD_IN_SAMPLES];
348     S_FM_VOICE              fmVoices[NUM_FM_VOICES];
349 #endif
350 
351 #ifdef _WT_SYNTH
352     S_WT_VOICE              wtVoices[NUM_WT_VOICES];
353 #endif
354 
355 #ifdef _REVERB
356     EAS_PCM                 reverbSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
357 #endif
358 
359 #ifdef _CHORUS
360     EAS_PCM                 chorusSendBuffer[NUM_OUTPUT_CHANNELS * SYNTH_UPDATE_PERIOD_IN_SAMPLES];
361 #endif
362     S_SYNTH_VOICE           voices[MAX_SYNTH_VOICES];
363 
364     EAS_SNDLIB_HANDLE       pGlobalEAS;
365 
366 #ifdef DLS_SYNTHESIZER
367     S_DLS                   *pGlobalDLS;
368 #endif
369 
370 #ifdef _SPLIT_ARCHITECTURE
371     EAS_FRAME_BUFFER_HANDLE pFrameBuffer;
372 #endif
373 
374 #if defined(_SECONDARY_SYNTH) || defined(EAS_SPLIT_WT_SYNTH)
375     EAS_U16                 maxPolyphonyPrimary;
376     EAS_U16                 maxPolyphonySecondary;
377 #endif
378 
379     EAS_I32                 workload;
380     EAS_I32                 maxWorkLoad;
381 
382     EAS_U16                 activeVoices;
383     EAS_U16                 maxPolyphony;
384 
385     EAS_U16                 age;
386 
387 /* limits the number of voice starts in a frame for split architecture */
388 #ifdef MAX_VOICE_STARTS
389     EAS_U16                 numVoiceStarts;
390 #endif
391 } S_VOICE_MGR;
392 
393 #endif /* #ifdef _EAS_SYNTH_H */
394 
395 
396