1 /*----------------------------------------------------------------------------
2  *
3  * File:
4  * eas_mdls.c
5  *
6  * Contents and purpose:
7  * This file contains DLS to EAS converter.
8  *
9  * Copyright (c) 2005 Sonic Network Inc.
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: 818 $
26  *   $Date: 2007-08-02 15:19:41 -0700 (Thu, 02 Aug 2007) $
27  *----------------------------------------------------------------------------
28 */
29 
30 /*
31  * NOTES:
32  *
33  * Processor Endian-ness:
34  *
35  * We use the EAS_HWGetDWord() and EAS_HWGetWord () functions
36  * extensively in this module. It would probably be faster to read
37  * an entire data structure, but this introduces the problem of
38  * sensitivity to processor endian-ness to the parser. By utlilizing
39  * the host wrapper functions, we avoid having to flip bytes around
40  * for big-endian processors. The default host wrapper versions of
41  * these functions are insensitive to processor endian-ness due to
42  * the fact that they read the file as a byte stream.
43  *
44  * Dynamic Memory:
45  *
46  * Dynamic memory allocation is a risky proposition in a mobile
47  * device. The memory can become fragmented, resulting in an
48  * inability to allocate a memory block, or garbage collection
49  * routines can use many CPU cycles. Either can contribute to
50  * failures of critical systems. Therefore, we try to minimize the
51  * number of memory allocations we make.
52  *
53  * We allocate a single large block of memory for the entire
54  * converted DLS collection, including the articulation data and
55  * samples. This block is then sub-allocated for the various
56  * data structures.
57  *
58  * Parser Overview:
59  *
60  * We make two passes through the file, the first pass to count the
61  * number of instruments, regions, etc. and allocate memory for
62  * them. The second pass parses the data into the allocated data
63  * structures.
64  *
65  * Conditional chunks are challenging in that they can occur
66  * anywhere in the list chunk that contains them. To simplify, we
67  * parse the blocks in a list in specific order, no matter which
68  * order they appear in the file. This way we don't allocate memory
69  * and parse a block that we end up throwing away later due to
70  * a conditional chunk.
71  *
72  * Assumptions that may bite us in the future:
73  *
74  * We make some assumptions to simplify things. The most fundamental
75  * assumption is that there will be no more than one of any type of
76  * chunk in a list. While this is consistent with the block diagram
77  * of the file layout in the mDLS spec, there is nothing in the
78  * spec that precludes having mulitple lar2 or rgn2 chunks, with
79  * conditional blocks that dictate their usage.
80  *
81  * DLS -> EAS Conversion Process:
82  *
83  * Another challenge is that the DLS structure does not map well to
84  * the current EAS sound library structure. Not all DLS constructs
85  * are supported, and data from DLS structures must sometimes be
86  * mapped to multiple EAS data structures. To simplify the process,
87  * the EAS region, articulation, and envelopes are treated as a
88  * single combined unit. Thus for each region, there must be one
89  * articulation element and two envelope elements.
90  *
91  * The sample processing is also a multi-step process. First the
92  * ptbl chunk is pre-parsed to determine the number of samples
93  * in the collection. The next step is to parse the instrument data
94  * to determine which samples are actually used by instruments.
95  * Some samples may not be used because they are used only in
96  * conditional blocks that the synthesizer cannot parse, or the
97  * author neglected to remove unused samples from the collection.
98  * In the next step, the active samples are read into memory and
99  * converted to the appropriate playback format. Finally, as the
100  * instruments are processed, the links are made to the samples and
101  * wsmp data is extracted for the region and articulation data
102  * structures.
103 */
104 
105 #ifndef _FILTER_ENABLED
106 #error "Filter must be enabled if DLS_SYNTHESIZER is enabled"
107 #endif
108 
109 /*------------------------------------
110  * includes
111  *------------------------------------
112 */
113 
114 /* this define allows us to use the sndlib.h structures as RW memory */
115 #define SCNST
116 
117 #include "eas_data.h"
118 #include "eas_host.h"
119 #include "eas_mdls.h"
120 #include "eas_math.h"
121 #include "dls.h"
122 #include "dls2.h"
123 #include "eas_report.h"
124 
125 //2 we should replace log10() function with fixed point routine in ConvertSampleRate()
126 /* lint is choking on the ARM math.h file, so we declare the log10 function here */
127 extern double log10(double x);
128 
129 /*------------------------------------
130  * defines
131  *------------------------------------
132 */
133 
134 // #define _DEBUG_DLS
135 
136 #define DLS_MAX_WAVE_COUNT      1024
137 #define DLS_MAX_ART_COUNT       2048
138 #define DLS_MAX_REGION_COUNT    2048
139 #define DLS_MAX_INST_COUNT      256
140 #define MAX_DLS_WAVE_SIZE       (1024*1024)
141 
142 #ifndef EAS_U32_MAX
143 #define EAS_U32_MAX             (4294967295U)
144 #endif
145 
146 #ifndef EAS_I32_MAX
147 #define EAS_I32_MAX             (2147483647)
148 #endif
149 
150 /*------------------------------------
151  * typedefs
152  *------------------------------------
153 */
154 
155 /* offsets to articulation data */
156 typedef enum
157 {
158     PARAM_MODIFIED = 0,
159     PARAM_MOD_LFO_FREQ,
160     PARAM_MOD_LFO_DELAY,
161 
162     PARAM_VIB_LFO_FREQ,
163     PARAM_VIB_LFO_DELAY,
164 
165     PARAM_VOL_EG_DELAY,
166     PARAM_VOL_EG_ATTACK,
167     PARAM_VOL_EG_HOLD,
168     PARAM_VOL_EG_DECAY,
169     PARAM_VOL_EG_SUSTAIN,
170     PARAM_VOL_EG_RELEASE,
171     PARAM_VOL_EG_SHUTDOWN,
172     PARAM_VOL_EG_VEL_TO_ATTACK,
173     PARAM_VOL_EG_KEY_TO_DECAY,
174     PARAM_VOL_EG_KEY_TO_HOLD,
175 
176     PARAM_MOD_EG_DELAY,
177     PARAM_MOD_EG_ATTACK,
178     PARAM_MOD_EG_HOLD,
179     PARAM_MOD_EG_DECAY,
180     PARAM_MOD_EG_SUSTAIN,
181     PARAM_MOD_EG_RELEASE,
182     PARAM_MOD_EG_VEL_TO_ATTACK,
183     PARAM_MOD_EG_KEY_TO_DECAY,
184     PARAM_MOD_EG_KEY_TO_HOLD,
185 
186     PARAM_INITIAL_FC,
187     PARAM_INITIAL_Q,
188     PARAM_MOD_LFO_TO_FC,
189     PARAM_MOD_LFO_CC1_TO_FC,
190     PARAM_MOD_LFO_CHAN_PRESS_TO_FC,
191     PARAM_MOD_EG_TO_FC,
192     PARAM_VEL_TO_FC,
193     PARAM_KEYNUM_TO_FC,
194 
195     PARAM_MOD_LFO_TO_GAIN,
196     PARAM_MOD_LFO_CC1_TO_GAIN,
197     PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN,
198     PARAM_VEL_TO_GAIN,
199 
200     PARAM_TUNING,
201     PARAM_KEYNUM_TO_PITCH,
202     PARAM_VIB_LFO_TO_PITCH,
203     PARAM_VIB_LFO_CC1_TO_PITCH,
204     PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH,
205     PARAM_MOD_LFO_TO_PITCH,
206     PARAM_MOD_LFO_CC1_TO_PITCH,
207     PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH,
208     PARAM_MOD_EG_TO_PITCH,
209 
210     PARAM_DEFAULT_PAN,
211     PARAM_MIDI_CC91_TO_REVERB_SEND,
212     PARAM_DEFAULT_REVERB_SEND,
213     PARAM_MIDI_CC93_TO_CHORUS_SEND,
214     PARAM_DEFAULT_CHORUS_SEND,
215     PARAM_TABLE_SIZE
216 } E_ART_INDEX;
217 
218 /* temporary data structure combining region, articulation, and envelope data */
219 typedef struct s_art_dls_tag
220 {
221     EAS_I16     values[PARAM_TABLE_SIZE];
222 } S_DLS_ART_VALUES;
223 
224 /* temporary data structure for wlnk chunk data */
225 typedef struct
226 {
227     EAS_I32 gain;
228     EAS_U32 loopStart;
229     EAS_U32 loopLength;
230     EAS_U32 sampleRate;
231     EAS_U16 bitsPerSample;
232     EAS_I16 fineTune;
233     EAS_U8  unityNote;
234 } S_WSMP_DATA;
235 
236 /* temporary data structure used while parsing a DLS file */
237 typedef struct
238 {
239     S_DLS               *pDLS;
240     EAS_HW_DATA_HANDLE  hwInstData;
241     EAS_FILE_HANDLE     fileHandle;
242     S_WSMP_DATA         *wsmpData;
243     EAS_U32             instCount;
244     EAS_U32             regionCount;
245     EAS_U32             artCount;
246     EAS_U32             waveCount;
247     EAS_U32             wavePoolSize;
248     EAS_U32             wavePoolOffset;
249     EAS_BOOL            bigEndian;
250     EAS_BOOL            filterUsed;
251 } SDLS_SYNTHESIZER_DATA;
252 
253 /* connection lookup table */
254 typedef struct s_connection_tag
255 {
256     EAS_U16 source;
257     EAS_U16 control;
258     EAS_U16 destination;
259     EAS_U16 connection;
260 } S_CONNECTION;
261 
262 static const S_CONNECTION connTable[] =
263 {
264     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_FREQUENCY, PARAM_MOD_LFO_FREQ },
265     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_LFO_STARTDELAY, PARAM_MOD_LFO_DELAY},
266 
267     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_FREQUENCY, PARAM_VIB_LFO_FREQ },
268     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_VIB_STARTDELAY, PARAM_VIB_LFO_DELAY },
269 
270     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DELAYTIME, PARAM_VOL_EG_DELAY },
271     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_ATTACK },
272     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_HOLD },
273     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_DECAY },
274     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SUSTAINLEVEL, PARAM_VOL_EG_SUSTAIN },
275     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_RELEASETIME, PARAM_VOL_EG_RELEASE },
276     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG1_SHUTDOWNTIME, PARAM_VOL_EG_SHUTDOWN },
277     { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG1_ATTACKTIME, PARAM_VOL_EG_VEL_TO_ATTACK },
278     { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_DECAYTIME, PARAM_VOL_EG_KEY_TO_DECAY },
279     { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG1_HOLDTIME, PARAM_VOL_EG_KEY_TO_HOLD },
280 
281     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DELAYTIME, PARAM_MOD_EG_DELAY },
282     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_ATTACK },
283     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_HOLD },
284     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_DECAY },
285     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_SUSTAINLEVEL, PARAM_MOD_EG_SUSTAIN },
286     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_EG2_RELEASETIME, PARAM_MOD_EG_RELEASE },
287     { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_EG2_ATTACKTIME, PARAM_MOD_EG_VEL_TO_ATTACK },
288     { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_DECAYTIME, PARAM_MOD_EG_KEY_TO_DECAY },
289     { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_EG2_HOLDTIME, PARAM_MOD_EG_KEY_TO_HOLD },
290 
291     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_INITIAL_FC },
292     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_FILTER_Q, PARAM_INITIAL_Q },
293     { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_TO_FC },
294     { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CC1_TO_FC },
295     { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_LFO_CHAN_PRESS_TO_FC },
296     { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_MOD_EG_TO_FC },
297     { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_VEL_TO_FC },
298     { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_FILTER_CUTOFF, PARAM_KEYNUM_TO_FC },
299 
300     { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_MOD_LFO_TO_GAIN },
301     { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_GAIN, PARAM_MOD_LFO_CC1_TO_GAIN },
302     { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_GAIN, PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN },
303     { CONN_SRC_KEYONVELOCITY, CONN_SRC_NONE, CONN_DST_GAIN, PARAM_VEL_TO_GAIN },
304 
305     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_TUNING },
306     { CONN_SRC_KEYNUMBER, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_KEYNUM_TO_PITCH },
307     { CONN_SRC_VIBRATO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_VIB_LFO_TO_PITCH },
308     { CONN_SRC_VIBRATO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_VIB_LFO_CC1_TO_PITCH },
309     { CONN_SRC_VIBRATO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH },
310     { CONN_SRC_LFO, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_LFO_TO_PITCH },
311     { CONN_SRC_LFO, CONN_SRC_CC1, CONN_DST_PITCH, PARAM_MOD_LFO_CC1_TO_PITCH },
312     { CONN_SRC_LFO, CONN_SRC_CHANNELPRESSURE, CONN_DST_PITCH, PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH },
313     { CONN_SRC_EG2, CONN_SRC_NONE, CONN_DST_PITCH, PARAM_MOD_EG_TO_PITCH },
314 
315     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_PAN, PARAM_DEFAULT_PAN },
316     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_DEFAULT_REVERB_SEND },
317     { CONN_SRC_CC91, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC91_TO_REVERB_SEND },
318     { CONN_SRC_NONE, CONN_SRC_NONE, CONN_DST_CHORUS, PARAM_DEFAULT_CHORUS_SEND },
319     { CONN_SRC_CC93, CONN_SRC_NONE, CONN_DST_REVERB, PARAM_MIDI_CC93_TO_CHORUS_SEND }
320 };
321 #define ENTRIES_IN_CONN_TABLE (sizeof(connTable)/sizeof(S_CONNECTION))
322 
323 static const S_DLS_ART_VALUES defaultArt =
324 {
325     0,              /* not modified */
326     -851,           /* Mod LFO frequency: 5 Hz */
327     -7973,          /* Mod LFO delay: 10 milliseconds */
328 
329     -851,           /* Vib LFO frequency: 5 Hz */
330     -7973,          /* Vib LFO delay: 10 milliseconds */
331 
332     -32768,         /* EG1 delay time: 0 secs */
333     -32768,         /* EG1 attack time: 0 secs */
334     -32768,         /* EG1 hold time: 0 secs */
335     -32768,         /* EG1 decay time: 0 secs */
336     1000,           /* EG1 sustain level: 100.0% */
337     -32768,         /* EG1 release time: 0 secs */
338     -7271,          /* EG1 shutdown time: 15 msecs */
339     0,              /* EG1 velocity to attack: 0 time cents */
340     0,              /* EG1 key number to decay: 0 time cents */
341     0,              /* EG1 key number to hold: 0 time cents */
342 
343     -32768,         /* EG2 delay time: 0 secs */
344     -32768,         /* EG2 attack time: 0 secs */
345     -32768,         /* EG2 hold time: 0 secs */
346     -32768,         /* EG2 decay time: 0 secs */
347     1000,           /* EG2 sustain level: 100.0% */
348     -32768,         /* EG2 release time: 0 secs */
349     0,              /* EG2 velocity to attack: 0 time cents */
350     0,              /* EG2 key number to decay: 0 time cents */
351     0,              /* EG2 key number to hold: 0 time cents */
352 
353     0x7fff,         /* Initial Fc: Disabled */
354     0,              /* Initial Q: 0 dB */
355     0,              /* Mod LFO to Fc: 0 cents */
356     0,              /* Mod LFO CC1 to Fc: 0 cents */
357     0,              /* Mod LFO channel pressure to Fc: 0 cents */
358     0,              /* EG2 to Fc: 0 cents */
359     0,              /* Velocity to Fc: 0 cents */
360     0,              /* Key number to Fc: 0 cents */
361 
362     0,              /* Mod LFO to gain: 0 dB */
363     0,              /* Mod LFO CC1 to gain: 0 dB */
364     0,              /* Mod LFO channel pressure to gain: 0 dB */
365     960,            /* Velocity to gain: 96 dB */
366 
367     0,              /* Tuning: 0 cents */
368     12800,          /* Key number to pitch: 12,800 cents */
369     0,              /* Vibrato to pitch: 0 cents */
370     0,              /* Vibrato CC1 to pitch: 0 cents */
371     0,              /* Vibrato channel pressure to pitch: 0 cents */
372     0,              /* Mod LFO to pitch: 0 cents */
373     0,              /* Mod LFO CC1 to pitch: 0 cents */
374     0,              /* Mod LFO channel pressure to pitch: 0 cents */
375     0,              /* Mod EG to pitch: 0 cents */
376 
377     0,              /* Default pan: 0.0% */
378     0,              /* Default reverb send: 0.0% */
379     1000,           /* Default CC91 to reverb send: 100.0% */
380     0,              /* Default chorus send: 0.0% */
381     1000            /* Default CC93 to chorus send: 100.0% */
382 };
383 
384 /*------------------------------------
385  * local variables
386  *------------------------------------
387 */
388 
389 #if defined(_8_BIT_SAMPLES)
390 static const EAS_INT bitDepth = 8;
391 #elif defined(_16_BIT_SAMPLES)
392 static const EAS_INT bitDepth = 16;
393 #else
394 #error "Must define _8_BIT_SAMPLES or _16_BIT_SAMPLES"
395 #endif
396 
397 static const EAS_U32 outputSampleRate = _OUTPUT_SAMPLE_RATE;
398 static const EAS_I32 dlsRateConvert = DLS_RATE_CONVERT;
399 static const EAS_I32 dlsLFOFrequencyConvert = DLS_LFO_FREQUENCY_CONVERT;
400 
401 /*------------------------------------
402  * inline functions
403  *------------------------------------
404 */
PtrOfs(void * p,EAS_I32 offset)405 EAS_INLINE void *PtrOfs (void *p, EAS_I32 offset)
406 {
407     return (void*) (((EAS_U8*) p) + offset);
408 }
409 
410 /*------------------------------------
411  * prototypes
412  *------------------------------------
413 */
414 static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize);
415 static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wsmpPos, EAS_I32 wsmpSize);
416 static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex);
417 static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p);
418 static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p);
419 static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *p, EAS_SAMPLE *pSample, EAS_U32 sampleLen);
420 static EAS_RESULT Parse_lins(SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size);
421 static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size);
422 static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale);
423 static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions);
424 static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex);
425 static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn);
426 static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt);
427 static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt);
428 static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex);
429 static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue);
430 static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp);
431 static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt,  EAS_U16 artIndex);
432 static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate);
433 static EAS_I16 ConvertSustain (EAS_I32 sustain);
434 static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents);
435 static EAS_I8 ConvertPan (EAS_I32 pan);
436 static EAS_U8 ConvertQ (EAS_I32 q);
437 
438 #ifdef _DEBUG_DLS
439 static void DumpDLS (S_EAS *pEAS);
440 #endif
441 
442 
443 /*----------------------------------------------------------------------------
444  * DLSParser ()
445  *----------------------------------------------------------------------------
446  * Purpose:
447  *
448  * Inputs:
449  * pEASData - pointer to over EAS data instance
450  * fileHandle - file handle for input file
451  * offset - offset into file where DLS data starts
452  *
453  * Outputs:
454  * EAS_RESULT
455  * ppEAS - address of pointer to alternate EAS wavetable
456  *
457  *----------------------------------------------------------------------------
458 */
DLSParser(EAS_HW_DATA_HANDLE hwInstData,EAS_FILE_HANDLE fileHandle,EAS_I32 offset,EAS_DLSLIB_HANDLE * ppDLS)459 EAS_RESULT DLSParser (EAS_HW_DATA_HANDLE hwInstData, EAS_FILE_HANDLE fileHandle, EAS_I32 offset, EAS_DLSLIB_HANDLE *ppDLS)
460 {
461     EAS_RESULT result;
462     SDLS_SYNTHESIZER_DATA dls;
463     EAS_U32 temp;
464     EAS_I32 pos;
465     EAS_I32 chunkPos;
466     EAS_I32 size;
467     EAS_I32 instSize;
468     EAS_I32 rgnPoolSize;
469     EAS_I32 artPoolSize;
470     EAS_I32 waveLenSize;
471     EAS_I32 endDLS;
472     EAS_I32 wvplPos;
473     EAS_I32 wvplSize;
474     EAS_I32 linsPos;
475     EAS_I32 linsSize;
476     EAS_I32 ptblPos;
477     EAS_I32 ptblSize;
478     void *p;
479 
480     /* zero counts and pointers */
481     EAS_HWMemSet(&dls, 0, sizeof(dls));
482 
483     /* save file handle and hwInstData to save copying pointers around */
484     dls.hwInstData = hwInstData;
485     dls.fileHandle = fileHandle;
486 
487     /* NULL return value in case of error */
488     *ppDLS = NULL;
489 
490     /* seek to start of DLS and read in RIFF tag and set processor endian flag */
491     if ((result = EAS_HWFileSeek(dls.hwInstData, dls.fileHandle, offset)) != EAS_SUCCESS)
492         return result;
493     if ((result = EAS_HWReadFile(dls.hwInstData, dls.fileHandle, &temp, sizeof(temp), &size)) != EAS_SUCCESS)
494         return result;
495 
496     /* check for processor endian-ness */
497     dls.bigEndian = (temp == CHUNK_RIFF);
498 
499     /* first chunk should be DLS */
500     pos = offset;
501     if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
502         return result;
503     if (temp != CHUNK_DLS)
504     {
505         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Expected DLS chunk, got %08lx\n", temp); */ }
506         return EAS_ERROR_FILE_FORMAT;
507     }
508 
509     /* no instrument or wavepool chunks */
510     linsSize = wvplSize = ptblSize = linsPos = wvplPos = ptblPos = 0;
511 
512     /* scan the chunks in the DLS list */
513     endDLS = offset + size;
514     pos = offset + 12;
515     while (pos < endDLS)
516     {
517         chunkPos = pos;
518 
519         /* get the next chunk type */
520         if ((result = NextChunk(&dls, &pos, &temp, &size)) != EAS_SUCCESS)
521             return result;
522 
523         /* parse useful chunks */
524         switch (temp)
525         {
526             case CHUNK_CDL:
527                 if ((result = Parse_cdl(&dls, size, &temp)) != EAS_SUCCESS)
528                     return result;
529                 if (!temp)
530                     return EAS_ERROR_UNRECOGNIZED_FORMAT;
531                 break;
532 
533             case CHUNK_LINS:
534                 linsPos = chunkPos + 12;
535                 linsSize = size - 4;
536                 break;
537 
538             case CHUNK_WVPL:
539                 wvplPos = chunkPos + 12;
540                 wvplSize = size - 4;
541                 break;
542 
543             case CHUNK_PTBL:
544                 ptblPos = chunkPos + 8;
545                 ptblSize = size - 4;
546                 break;
547 
548             default:
549                 break;
550         }
551     }
552 
553     /* must have a lins chunk */
554     if (linsSize == 0)
555     {
556         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No lins chunk found"); */ }
557         return EAS_ERROR_UNRECOGNIZED_FORMAT;
558     }
559 
560     /* must have a wvpl chunk */
561     if (wvplSize == 0)
562     {
563         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No wvpl chunk found"); */ }
564         return EAS_ERROR_UNRECOGNIZED_FORMAT;
565     }
566 
567     /* must have a ptbl chunk */
568     if ((ptblSize == 0) || (ptblSize > DLS_MAX_WAVE_COUNT * sizeof(POOLCUE) + sizeof(POOLTABLE)))
569     {
570         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No ptbl chunk found"); */ }
571         return EAS_ERROR_UNRECOGNIZED_FORMAT;
572     }
573 
574     /* pre-parse the wave pool chunk */
575     if ((result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize)) != EAS_SUCCESS)
576         return result;
577 
578     /* limit check  */
579     if ((dls.waveCount == 0) || (dls.waveCount > DLS_MAX_WAVE_COUNT))
580     {
581         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #waves [%u]\n", dls.waveCount); */ }
582         return EAS_ERROR_FILE_FORMAT;
583     }
584 
585     /* allocate memory for wsmp data */
586     dls.wsmpData = EAS_HWMalloc(dls.hwInstData, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
587     if (dls.wsmpData == NULL)
588     {
589         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc for wsmp data failed\n"); */ }
590         return EAS_ERROR_MALLOC_FAILED;
591     }
592     EAS_HWMemSet(dls.wsmpData, 0, (EAS_I32) (sizeof(S_WSMP_DATA) * dls.waveCount));
593 
594     /* pre-parse the lins chunk */
595     result = Parse_lins(&dls, linsPos, linsSize);
596     if (result == EAS_SUCCESS)
597     {
598 
599         /* limit check  */
600         if ((dls.regionCount == 0) || (dls.regionCount > DLS_MAX_REGION_COUNT))
601         {
602             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #regions [%u]\n", dls.regionCount); */ }
603             return EAS_ERROR_FILE_FORMAT;
604         }
605 
606         /* limit check  */
607         if ((dls.artCount == 0) || (dls.artCount > DLS_MAX_ART_COUNT))
608         {
609             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #articulations [%u]\n", dls.regionCount); */ }
610             return EAS_ERROR_FILE_FORMAT;
611         }
612 
613         /* limit check  */
614         if ((dls.instCount == 0) || (dls.instCount > DLS_MAX_INST_COUNT))
615         {
616             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS file contains invalid #instruments [%u]\n", dls.instCount); */ }
617             return EAS_ERROR_FILE_FORMAT;
618         }
619 
620         /* Allocate memory for the converted DLS data */
621         /* calculate size of instrument data */
622         instSize = (EAS_I32) (sizeof(S_PROGRAM) * dls.instCount);
623 
624         /* calculate size of region pool */
625         rgnPoolSize = (EAS_I32) (sizeof(S_DLS_REGION) * dls.regionCount);
626 
627         /* calculate size of articulation pool, add one for default articulation */
628         dls.artCount++;
629         artPoolSize = (EAS_I32) (sizeof(S_DLS_ARTICULATION) * dls.artCount);
630 
631         /* calculate size of wave length and offset arrays */
632         waveLenSize = (EAS_I32) (dls.waveCount * sizeof(EAS_U32));
633 
634         /* calculate final memory size */
635         size = (EAS_I32) sizeof(S_EAS) + instSize + rgnPoolSize + artPoolSize + (2 * waveLenSize) + (EAS_I32) dls.wavePoolSize;
636         if (size <= 0) {
637             return EAS_ERROR_FILE_FORMAT;
638         }
639 
640         /* allocate the main EAS chunk */
641         dls.pDLS = EAS_HWMalloc(dls.hwInstData, size);
642         if (dls.pDLS == NULL)
643         {
644             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "EAS_HWMalloc failed for DLS memory allocation size %ld\n", size); */ }
645             return EAS_ERROR_MALLOC_FAILED;
646         }
647         EAS_HWMemSet(dls.pDLS, 0, size);
648         dls.pDLS->refCount = 1;
649         p = PtrOfs(dls.pDLS, sizeof(S_EAS));
650 
651         /* setup pointer to programs */
652         dls.pDLS->numDLSPrograms = (EAS_U16) dls.instCount;
653         dls.pDLS->pDLSPrograms = p;
654         p = PtrOfs(p, instSize);
655 
656         /* setup pointer to regions */
657         dls.pDLS->pDLSRegions = p;
658         dls.pDLS->numDLSRegions = (EAS_U16) dls.regionCount;
659         p = PtrOfs(p, rgnPoolSize);
660 
661         /* setup pointer to articulations */
662         dls.pDLS->numDLSArticulations = (EAS_U16) dls.artCount;
663         dls.pDLS->pDLSArticulations = p;
664         p = PtrOfs(p, artPoolSize);
665 
666         /* setup pointer to wave length table */
667         dls.pDLS->numDLSSamples = (EAS_U16) dls.waveCount;
668         dls.pDLS->pDLSSampleLen = p;
669         p = PtrOfs(p, waveLenSize);
670 
671         /* setup pointer to wave offsets table */
672         dls.pDLS->pDLSSampleOffsets = p;
673         p = PtrOfs(p, waveLenSize);
674 
675         /* setup pointer to wave pool */
676         dls.pDLS->pDLSSamples = p;
677 
678         /* clear filter flag */
679         dls.filterUsed = EAS_FALSE;
680 
681         /* parse the wave pool and load samples */
682         result = Parse_ptbl(&dls, ptblPos, wvplPos, wvplSize);
683     }
684 
685     /* create the default articulation */
686     if (dls.pDLS) {
687         Convert_art(&dls, &defaultArt, 0);
688         dls.artCount = 1;
689     }
690 
691     /* parse the lins chunk and load instruments */
692     dls.regionCount = dls.instCount = 0;
693     if (result == EAS_SUCCESS)
694         result = Parse_lins(&dls, linsPos, linsSize);
695 
696     /* clean up any temporary objects that were allocated */
697     if (dls.wsmpData)
698         EAS_HWFree(dls.hwInstData, dls.wsmpData);
699 
700     /* if successful, return a pointer to the EAS collection */
701     if (result == EAS_SUCCESS)
702     {
703         *ppDLS = dls.pDLS;
704 #ifdef _DEBUG_DLS
705         DumpDLS(dls.pDLS);
706 #endif
707     }
708 
709     /* something went wrong, deallocate the EAS collection */
710     else
711         DLSCleanup(dls.hwInstData, dls.pDLS);
712 
713     return result;
714 }
715 
716 /*----------------------------------------------------------------------------
717  * DLSCleanup ()
718  *----------------------------------------------------------------------------
719  * Purpose:
720  *
721  * Inputs:
722  * pEASData - pointer to over EAS data instance
723  * pEAS - pointer to alternate EAS wavetable
724  *
725  * Outputs:
726  * EAS_RESULT
727  *
728  *----------------------------------------------------------------------------
729 */
DLSCleanup(EAS_HW_DATA_HANDLE hwInstData,S_DLS * pDLS)730 EAS_RESULT DLSCleanup (EAS_HW_DATA_HANDLE hwInstData, S_DLS *pDLS)
731 {
732 
733     /* free the allocated memory */
734     if (pDLS)
735     {
736         if (pDLS->refCount)
737         {
738             if (--pDLS->refCount == 0)
739                 EAS_HWFree(hwInstData, pDLS);
740         }
741     }
742     return EAS_SUCCESS;
743 }
744 
745 /*----------------------------------------------------------------------------
746  * DLSAddRef ()
747  *----------------------------------------------------------------------------
748  * Increment reference count
749  *----------------------------------------------------------------------------
750 */
DLSAddRef(S_DLS * pDLS)751 void DLSAddRef (S_DLS *pDLS)
752 {
753     if (pDLS)
754         pDLS->refCount++;
755 }
756 
757 /*----------------------------------------------------------------------------
758  * NextChunk ()
759  *----------------------------------------------------------------------------
760  * Purpose:
761  * Returns the type and size of the next chunk in the file
762  *
763  * Inputs:
764  *
765  * Outputs:
766  *
767  * Side Effects:
768  *----------------------------------------------------------------------------
769 */
NextChunk(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 * pPos,EAS_U32 * pChunkType,EAS_I32 * pSize)770 static EAS_RESULT NextChunk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 *pPos, EAS_U32 *pChunkType, EAS_I32 *pSize)
771 {
772     EAS_RESULT result;
773 
774     /* seek to start of chunk */
775     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, *pPos)) != EAS_SUCCESS)
776         return result;
777 
778     /* read the chunk type */
779     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
780         return result;
781 
782     /* read the chunk size */
783     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pSize, EAS_FALSE)) != EAS_SUCCESS)
784         return result;
785 
786     /* get form type for RIFF and LIST types */
787     if ((*pChunkType == CHUNK_RIFF) || (*pChunkType == CHUNK_LIST))
788     {
789 
790         /* read the form type */
791         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pChunkType, EAS_TRUE)) != EAS_SUCCESS)
792             return result;
793 
794     }
795 
796     /* calculate start of next chunk */
797     *pPos += *pSize + 8;
798 
799     /* adjust to word boundary */
800     if (*pPos & 1)
801         (*pPos)++;
802 
803     return EAS_SUCCESS;
804 }
805 
806 /*----------------------------------------------------------------------------
807  * Parse_ptbl ()
808  *----------------------------------------------------------------------------
809  * Purpose:
810  *
811  *
812  * Inputs:
813  *
814  *
815  * Outputs:
816  *
817  *
818  *----------------------------------------------------------------------------
819 */
Parse_ptbl(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 wtblPos,EAS_I32 wtblSize)820 static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wtblPos, EAS_I32 wtblSize)
821 {
822     EAS_RESULT result;
823     EAS_U32 temp;
824     EAS_FILE_HANDLE tempFile;
825     EAS_U16 waveIndex;
826 
827     /* seek to start of chunk */
828     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
829         return result;
830 
831     /* get the structure size */
832     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS)
833         return result;
834 
835     /* get the number of waves */
836     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS)
837         return result;
838 
839 #if 0
840     /* just need the wave count on the first pass */
841     if (!pDLSData->pDLS)
842         return EAS_SUCCESS;
843 #endif
844 
845     /* open duplicate file handle */
846     if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS)
847         return result;
848 
849     /* read to end of chunk */
850     for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++)
851     {
852 
853         /* get the offset to the wave and make sure it is within the wtbl chunk */
854         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS)
855             return result;
856         if (temp > (EAS_U32) wtblSize)
857         {
858             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ }
859             EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
860             return EAS_ERROR_FILE_FORMAT;
861         }
862 
863         /* parse the wave */
864         if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32)  temp, waveIndex)) != EAS_SUCCESS)
865             return result;
866     }
867 
868     /* close the temporary handle and return */
869     EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
870     return EAS_SUCCESS;
871 }
872 
873 /*----------------------------------------------------------------------------
874  * Parse_wave ()
875  *----------------------------------------------------------------------------
876  * Purpose:
877  *
878  *
879  * Inputs:
880  *
881  *
882  * Outputs:
883  *
884  *
885  *----------------------------------------------------------------------------
886 */
Parse_wave(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_U16 waveIndex)887 static EAS_RESULT Parse_wave (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U16 waveIndex)
888 {
889     EAS_RESULT result;
890     EAS_U32 temp;
891     EAS_I32 size;
892     EAS_I32 endChunk;
893     EAS_I32 chunkPos;
894     EAS_I32 wsmpPos = 0;
895     EAS_I32 fmtPos = 0;
896     EAS_I32 dataPos = 0;
897     EAS_I32 dataSize = 0;
898     S_WSMP_DATA *p;
899     void *pSample;
900     S_WSMP_DATA wsmp;
901 
902     /* seek to start of chunk */
903     chunkPos = pos + 12;
904     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
905         return result;
906 
907     /* get the chunk type */
908     if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
909         return result;
910 
911     /* make sure it is a wave chunk */
912     if (temp != CHUNK_WAVE)
913     {
914         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Offset in ptbl does not point to wave chunk\n"); */ }
915         return EAS_ERROR_FILE_FORMAT;
916     }
917 
918     /* read to end of chunk */
919     pos = chunkPos;
920     endChunk = pos + size;
921     while (pos < endChunk)
922     {
923         chunkPos = pos;
924 
925         /* get the chunk type */
926         if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
927             return result;
928 
929         /* parse useful chunks */
930         switch (temp)
931         {
932             case CHUNK_WSMP:
933                 wsmpPos = chunkPos + 8;
934                 break;
935 
936             case CHUNK_FMT:
937                 fmtPos = chunkPos + 8;
938                 break;
939 
940             case CHUNK_DATA:
941                 dataPos = chunkPos + 8;
942                 dataSize = size;
943                 break;
944 
945             default:
946                 break;
947         }
948     }
949 
950     // limit to reasonable size
951     if (dataSize < 0 || dataSize > MAX_DLS_WAVE_SIZE)
952     {
953         return EAS_ERROR_SOUND_LIBRARY;
954     }
955 
956     /* for first pass, use temporary variable */
957     if (pDLSData->pDLS == NULL)
958         p = &wsmp;
959     else
960         p = &pDLSData->wsmpData[waveIndex];
961 
962     /* set the defaults */
963     p->fineTune = 0;
964     p->unityNote = 60;
965     p->gain = 0;
966     p->loopStart = 0;
967     p->loopLength = 0;
968 
969     /* must have a fmt chunk */
970     if (!fmtPos)
971     {
972         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no fmt chunk\n"); */ }
973         return EAS_ERROR_UNRECOGNIZED_FORMAT;
974     }
975 
976     /* must have a data chunk */
977     if (!dataPos)
978     {
979         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS wave chunk has no data chunk\n"); */ }
980         return EAS_ERROR_UNRECOGNIZED_FORMAT;
981     }
982 
983     /* parse the wsmp chunk */
984     if (wsmpPos)
985     {
986         if ((result = Parse_wsmp(pDLSData, wsmpPos, p)) != EAS_SUCCESS)
987             return result;
988     }
989 
990     /* parse the fmt chunk */
991     if ((result = Parse_fmt(pDLSData, fmtPos, p)) != EAS_SUCCESS)
992         return result;
993 
994     /* calculate the size of the wavetable needed. We need only half
995      * the memory for 16-bit samples when in 8-bit mode, and we need
996      * double the memory for 8-bit samples in 16-bit mode. For
997      * unlooped samples, we may use ADPCM. If so, we need only 1/4
998      * the memory.
999      *
1000      * We also need to add one for looped samples to allow for
1001      * the first sample to be copied to the end of the loop.
1002      */
1003 
1004     /* use ADPCM encode for unlooped 16-bit samples if ADPCM is enabled */
1005     /*lint -e{506} -e{774} groundwork for future version to support 8 & 16 bit */
1006     if (bitDepth == 8)
1007     {
1008         if (p->bitsPerSample == 8)
1009             size = dataSize;
1010         else
1011             /*lint -e{704} use shift for performance */
1012             size = dataSize >> 1;
1013         if (p->loopLength)
1014             size++;
1015     }
1016 
1017     else
1018     {
1019         if (p->bitsPerSample == 16)
1020             size = dataSize;
1021         else
1022             /*lint -e{703} use shift for performance */
1023             size = dataSize << 1;
1024         if (p->loopLength)
1025             size += 2;
1026     }
1027 
1028     /* for first pass, add size to wave pool size and return */
1029     if (pDLSData->pDLS == NULL)
1030     {
1031         pDLSData->wavePoolSize += (EAS_U32) size;
1032         return EAS_SUCCESS;
1033     }
1034 
1035     /* allocate memory and read in the sample data */
1036     pSample = (EAS_U8*)pDLSData->pDLS->pDLSSamples + pDLSData->wavePoolOffset;
1037     pDLSData->pDLS->pDLSSampleOffsets[waveIndex] = pDLSData->wavePoolOffset;
1038     pDLSData->pDLS->pDLSSampleLen[waveIndex] = (EAS_U32) size;
1039     pDLSData->wavePoolOffset += (EAS_U32) size;
1040     if (pDLSData->wavePoolOffset > pDLSData->wavePoolSize)
1041     {
1042         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Wave pool exceeded allocation\n"); */ }
1043         return EAS_ERROR_SOUND_LIBRARY;
1044     }
1045 
1046     if ((result = Parse_data(pDLSData, dataPos, dataSize, p, pSample, (EAS_U32)size)) != EAS_SUCCESS)
1047         return result;
1048 
1049     return EAS_SUCCESS;
1050 }
1051 
1052 /*----------------------------------------------------------------------------
1053  * Parse_wsmp ()
1054  *----------------------------------------------------------------------------
1055  * Purpose:
1056  *
1057  *
1058  * Inputs:
1059  *
1060  *
1061  * Outputs:
1062  *
1063  *
1064  *----------------------------------------------------------------------------
1065 */
Parse_wsmp(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,S_WSMP_DATA * p)1066 static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
1067 {
1068     EAS_RESULT result;
1069     EAS_U16 wtemp;
1070     EAS_U32 ltemp;
1071     EAS_U32 cbSize;
1072 
1073     /* seek to start of chunk */
1074     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1075         return result;
1076 
1077     /* get structure size */
1078     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS)
1079         return result;
1080 
1081     /* get unity note */
1082     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1083         return result;
1084     if (wtemp <= 127)
1085         p->unityNote = (EAS_U8) wtemp;
1086     else
1087     {
1088         p->unityNote = 60;
1089         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ }
1090     }
1091 
1092     /* get fine tune */
1093     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS)
1094         return result;
1095 
1096     /* get gain */
1097     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS)
1098         return result;
1099     if (p->gain > 0)
1100     {
1101         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ }
1102         p->gain = 0;
1103     }
1104 
1105     /* option flags */
1106     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1107         return result;
1108 
1109     /* sample loops */
1110     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1111         return result;
1112 
1113     /* if looped sample, get loop data */
1114     if (ltemp)
1115     {
1116 
1117         if (ltemp > 1)
1118             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ }
1119 
1120         /* skip ahead to loop data */
1121         if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS)
1122             return result;
1123 
1124         /* get structure size */
1125         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1126             return result;
1127 
1128         /* get loop type */
1129         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1130             return result;
1131 
1132         /* get loop start */
1133         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS)
1134             return result;
1135 
1136         /* get loop length */
1137         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS)
1138             return result;
1139 
1140         /* ensure no overflow */
1141         if (p->loopLength
1142             && ((p->loopStart > EAS_U32_MAX - p->loopLength)
1143                 || (p->loopStart + p->loopLength > EAS_U32_MAX / sizeof(EAS_SAMPLE))))
1144         {
1145             return EAS_FAILURE;
1146         }
1147     }
1148 
1149     return EAS_SUCCESS;
1150 }
1151 
1152 /*----------------------------------------------------------------------------
1153  * Parse_fmt ()
1154  *----------------------------------------------------------------------------
1155  * Purpose:
1156  *
1157  *
1158  * Inputs:
1159  *
1160  *
1161  * Outputs:
1162  *
1163  *
1164  *----------------------------------------------------------------------------
1165 */
Parse_fmt(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,S_WSMP_DATA * p)1166 static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
1167 {
1168     EAS_RESULT result;
1169     EAS_U16 wtemp;
1170     EAS_U32 ltemp;
1171 
1172     /* seek to start of chunk */
1173     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1174         return result;
1175 
1176     /* get format tag */
1177     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1178         return result;
1179     if (wtemp != WAVE_FORMAT_PCM)
1180     {
1181         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ }
1182         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1183     }
1184 
1185     /* get number of channels */
1186     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1187         return result;
1188     if (wtemp != 1)
1189     {
1190         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ }
1191         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1192     }
1193 
1194     /* get sample rate */
1195     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS)
1196         return result;
1197 
1198     /* bytes/sec */
1199     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
1200         return result;
1201 
1202     /* block align */
1203     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
1204         return result;
1205 
1206     /* bits/sample */
1207     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS)
1208         return result;
1209 
1210     if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16))
1211     {
1212         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ }
1213         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1214     }
1215 
1216     return EAS_SUCCESS;
1217 }
1218 
1219 #if defined( _8_BIT_SAMPLES)
1220 /*----------------------------------------------------------------------------
1221  * Parse_data ()
1222  *----------------------------------------------------------------------------
1223  * Purpose:
1224  *
1225  * NOTE: The optimized assembly versions of the interpolator require
1226  * an extra sample at the end of the loop - a copy of the first
1227  * sample. This routine must allocate an extra sample of data and
1228  * copy the first sample of the loop to the end.
1229  *
1230  * Inputs:
1231  *
1232  *
1233  * Outputs:
1234  *
1235  *
1236  *----------------------------------------------------------------------------
1237 */
Parse_data(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 size,S_WSMP_DATA * pWsmp,EAS_SAMPLE * pSample,EAS_U32 sampleLen)1238 static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample, EAS_U32 sampleLen)
1239 {
1240     EAS_RESULT result;
1241     EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE];
1242     EAS_I32 count;
1243     EAS_I32 i;
1244     EAS_I8 *p;
1245 
1246     /* seek to start of chunk */
1247     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1248         return result;
1249 
1250     /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */
1251     p = pSample;
1252     if (pWsmp->bitsPerSample == 8)
1253     {
1254         if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS)
1255             return result;
1256         for (i = 0; i < size; i++)
1257             /*lint -e{734} convert from unsigned to signed audio */
1258             *p++ ^= 0x80;
1259     }
1260 
1261     /* 16-bit samples, need to convert to 8-bit or ADPCM */
1262     else
1263     {
1264 
1265         while (size)
1266         {
1267             EAS_I8 *pInput;
1268 
1269             /* for undithered conversion, we're just copying the 8-bit data */
1270             if (pDLSData->bigEndian)
1271                 pInput = (EAS_I8*) convBuf;
1272             else
1273                 pInput = (EAS_I8*) convBuf + 1;
1274 
1275             /* read a small chunk of data and convert it */
1276             count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE);
1277             if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS)
1278                 return result;
1279             size -= count;
1280             /*lint -e{704} use shift for performance */
1281             count = count >> 1;
1282 
1283             while (count--)
1284             {
1285                 *p++ = *pInput;
1286                 pInput += 2;
1287             }
1288         }
1289     }
1290 
1291     /* for looped samples, copy the last sample to the end */
1292     if (pWsmp->loopLength)
1293     {
1294         if (sampleLen < sizeof(EAS_SAMPLE)
1295             || (pWsmp->loopStart + pWsmp->loopLength) * sizeof(EAS_SAMPLE) > sampleLen - sizeof(EAS_SAMPLE))
1296         {
1297             return EAS_FAILURE;
1298         }
1299 
1300         pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart];
1301     }
1302 
1303     return EAS_SUCCESS;
1304 }
1305 #elif defined(_16_BIT_SAMPLES)
1306 #error "16-bit DLS conversion not implemented yet"
1307 #else
1308 #error "Must specifiy _8_BIT_SAMPLES or _16_BIT_SAMPLES"
1309 #endif
1310 
1311 /*----------------------------------------------------------------------------
1312  * Parse_lins ()
1313  *----------------------------------------------------------------------------
1314  * Purpose:
1315  *
1316  *
1317  * Inputs:
1318  *
1319  *
1320  * Outputs:
1321  *
1322  *
1323  *----------------------------------------------------------------------------
1324 */
Parse_lins(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 size)1325 static EAS_RESULT Parse_lins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
1326 {
1327     EAS_RESULT result;
1328     EAS_U32 temp;
1329     EAS_I32 endChunk;
1330     EAS_I32 chunkPos;
1331 
1332     /* seek to start of chunk */
1333     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1334         return result;
1335 
1336     /* read to end of chunk */
1337     endChunk = pos + size;
1338     while (pos < endChunk)
1339     {
1340         chunkPos = pos;
1341 
1342         /* get the next chunk type */
1343         if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1344             return result;
1345 
1346         /* only instrument chunks are useful */
1347         if (temp != CHUNK_INS)
1348             continue;
1349 
1350         if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS)
1351             return result;
1352     }
1353 
1354     return EAS_SUCCESS;
1355 }
1356 
1357 /*----------------------------------------------------------------------------
1358  * Parse_ins ()
1359  *----------------------------------------------------------------------------
1360  * Purpose:
1361  *
1362  *
1363  * Inputs:
1364  *
1365  *
1366  * Outputs:
1367  *
1368  *
1369  *----------------------------------------------------------------------------
1370 */
Parse_ins(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 size)1371 static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
1372 {
1373     EAS_RESULT result;
1374     EAS_U32 temp;
1375     EAS_I32 chunkPos;
1376     EAS_I32 endChunk;
1377     EAS_I32 lrgnPos;
1378     EAS_I32 lrgnSize;
1379     EAS_I32 lartPos;
1380     EAS_I32 lartSize;
1381     EAS_I32 lar2Pos;
1382     EAS_I32 lar2Size;
1383     EAS_I32 inshPos;
1384     EAS_U32 regionCount;
1385     EAS_U32 locale;
1386     S_DLS_ART_VALUES art;
1387     S_PROGRAM *pProgram;
1388     EAS_U16 artIndex;
1389 
1390     /* seek to start of chunk */
1391     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1392         return result;
1393 
1394     /* no chunks yet */
1395     lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0;
1396 
1397     /* read to end of chunk */
1398     endChunk = pos + size;
1399     while (pos < endChunk)
1400     {
1401         chunkPos = pos;
1402 
1403         /* get the next chunk type */
1404         if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1405             return result;
1406 
1407         /* parse useful chunks */
1408         switch (temp)
1409         {
1410             case CHUNK_INSH:
1411                 inshPos = chunkPos + 8;
1412                 break;
1413 
1414             case CHUNK_LART:
1415                 lartPos = chunkPos + 12;
1416                 lartSize = size;
1417                 break;
1418 
1419             case CHUNK_LAR2:
1420                 lar2Pos = chunkPos + 12;
1421                 lar2Size = size;
1422                 break;
1423 
1424             case CHUNK_LRGN:
1425                 lrgnPos = chunkPos + 12;
1426                 lrgnSize = size;
1427                 break;
1428 
1429             default:
1430                 break;
1431         }
1432     }
1433 
1434     /* must have an lrgn to be useful */
1435     if (!lrgnPos)
1436     {
1437         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ }
1438         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1439     }
1440 
1441     /* must have an insh to be useful */
1442     if (!inshPos)
1443     {
1444         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ }
1445         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1446     }
1447 
1448     /* parse the instrument header */
1449     if ((result = Parse_insh(pDLSData, inshPos, &regionCount, &locale)) != EAS_SUCCESS)
1450         return result;
1451 
1452     /* initialize and parse the global data first */
1453     EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
1454     if (lartPos)
1455         if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
1456             return result;
1457     if (lar2Pos)
1458         if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
1459             return result;
1460 
1461     if (art.values[PARAM_MODIFIED])
1462     {
1463         artIndex = (EAS_U16) pDLSData->artCount;
1464         pDLSData->artCount++;
1465     }
1466 
1467     /* convert data on second pass */
1468     if (pDLSData->pDLS)
1469     {
1470 
1471         if (art.values[PARAM_MODIFIED])
1472             Convert_art(pDLSData, &art, artIndex);
1473 
1474         /* setup pointers */
1475         pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount];
1476 
1477         /* initialize instrument */
1478         pProgram->locale = locale;
1479         pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH;
1480 
1481     }
1482 
1483     /* parse the region data */
1484     if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS)
1485         return result;
1486 
1487     /* bump instrument count */
1488     pDLSData->instCount++;
1489     return EAS_SUCCESS;
1490 }
1491 
1492 /*----------------------------------------------------------------------------
1493  * Parse_insh ()
1494  *----------------------------------------------------------------------------
1495  * Purpose:
1496  *
1497  *
1498  * Inputs:
1499  *
1500  *
1501  * Outputs:
1502  *
1503  *
1504  *----------------------------------------------------------------------------
1505 */
Parse_insh(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_U32 * pRgnCount,EAS_U32 * pLocale)1506 static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale)
1507 {
1508     EAS_RESULT result;
1509     EAS_U32 bank;
1510     EAS_U32 program;
1511 
1512     /* seek to start of chunk */
1513     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1514         return result;
1515 
1516     /* get the region count and locale */
1517     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS)
1518         return result;
1519     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS)
1520         return result;
1521     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS)
1522         return result;
1523 
1524     /* verify the parameters are valid */
1525     if (bank & 0x7fff8080)
1526     {
1527         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ }
1528         bank &= 0xff7f;
1529     }
1530     if (program > 127)
1531     {
1532         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ }
1533         program &= 0x7f;
1534     }
1535 
1536     /* save the program number */
1537     *pLocale = (bank << 8) | program;
1538     return EAS_SUCCESS;
1539 }
1540 
1541 /*----------------------------------------------------------------------------
1542  * Parse_lrgn ()
1543  *----------------------------------------------------------------------------
1544  * Purpose:
1545  *
1546  *
1547  * Inputs:
1548  *
1549  *
1550  * Outputs:
1551  *
1552  *
1553  *----------------------------------------------------------------------------
1554 */
Parse_lrgn(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 size,EAS_U16 artIndex,EAS_U32 numRegions)1555 static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions)
1556 {
1557     EAS_RESULT result;
1558     EAS_U32 temp;
1559     EAS_I32 chunkPos;
1560     EAS_I32 endChunk;
1561     EAS_U16 regionCount;
1562 
1563     /* seek to start of chunk */
1564     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1565         return result;
1566 
1567     /* read to end of chunk */
1568     regionCount = 0;
1569     endChunk = pos + size;
1570     while (pos < endChunk)
1571     {
1572         chunkPos = pos;
1573 
1574         /* get the next chunk type */
1575         if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1576             return result;
1577 
1578         if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2))
1579         {
1580             if (regionCount == numRegions)
1581             {
1582                 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ }
1583                 return EAS_SUCCESS;
1584             }
1585             if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS)
1586                 return result;
1587             regionCount++;
1588         }
1589     }
1590 
1591     /* set a flag in the last region */
1592     if ((pDLSData->pDLS != NULL) && (regionCount > 0))
1593         pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION;
1594 
1595     return EAS_SUCCESS;
1596 }
1597 
1598 /*----------------------------------------------------------------------------
1599  * Parse_rgn ()
1600  *----------------------------------------------------------------------------
1601  * Purpose:
1602  *
1603  *
1604  * Inputs:
1605  *
1606  *
1607  * Outputs:
1608  *
1609  *
1610  *----------------------------------------------------------------------------
1611 */
Parse_rgn(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 size,EAS_U16 artIndex)1612 static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex)
1613 {
1614     EAS_RESULT result;
1615     EAS_U32 temp;
1616     EAS_I32 chunkPos;
1617     EAS_I32 endChunk;
1618     EAS_I32 rgnhPos;
1619     EAS_I32 lartPos;
1620     EAS_I32 lartSize;
1621     EAS_I32 lar2Pos;
1622     EAS_I32 lar2Size;
1623     EAS_I32 wlnkPos;
1624     EAS_I32 wsmpPos;
1625     EAS_U32 waveIndex;
1626     S_DLS_ART_VALUES art;
1627     S_WSMP_DATA wsmp;
1628     S_WSMP_DATA *pWsmp;
1629     EAS_U16 regionIndex;
1630 
1631     /* seek to start of chunk */
1632     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1633         return result;
1634 
1635     /* no chunks found yet */
1636     rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0;
1637     regionIndex = (EAS_U16) pDLSData->regionCount;
1638 
1639     /* read to end of chunk */
1640     endChunk = pos + size;
1641     while (pos < endChunk)
1642     {
1643         chunkPos = pos;
1644 
1645         /* get the next chunk type */
1646         if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1647             return result;
1648 
1649         /* parse useful chunks */
1650         switch (temp)
1651         {
1652             case CHUNK_CDL:
1653                 if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
1654                     return result;
1655 
1656                 /* if conditional chunk evaluates false, skip this list */
1657                 if (!temp)
1658                     return EAS_SUCCESS;
1659                 break;
1660 
1661             case CHUNK_RGNH:
1662                 rgnhPos = chunkPos + 8;
1663                 break;
1664 
1665             case CHUNK_WLNK:
1666                 wlnkPos = chunkPos + 8;
1667                 break;
1668 
1669             case CHUNK_WSMP:
1670                 wsmpPos = chunkPos + 8;
1671                 break;
1672 
1673             case CHUNK_LART:
1674                 lartPos = chunkPos + 12;
1675                 lartSize = size;
1676                 break;
1677 
1678             case CHUNK_LAR2:
1679                 lar2Pos = chunkPos + 12;
1680                 lar2Size = size;
1681                 break;
1682 
1683             default:
1684                 break;
1685         }
1686     }
1687 
1688     /* must have a rgnh chunk to be useful */
1689     if (!rgnhPos)
1690     {
1691         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ }
1692         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1693     }
1694 
1695     /* must have a wlnk chunk to be useful */
1696     if (!wlnkPos)
1697     {
1698         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ }
1699         return EAS_ERROR_UNRECOGNIZED_FORMAT;
1700     }
1701 
1702     /* parse wlnk chunk */
1703     if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS)
1704         return result;
1705     if (waveIndex >= pDLSData->waveCount)
1706     {
1707         return EAS_FAILURE;
1708     }
1709     pWsmp = &pDLSData->wsmpData[waveIndex];
1710 
1711     /* if there is any articulation data, parse it */
1712     EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
1713     if (lartPos)
1714     {
1715         if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
1716             return result;
1717     }
1718 
1719     if (lar2Pos)
1720     {
1721         if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
1722             return result;
1723     }
1724 
1725     /* if second pass, process region header */
1726     if (pDLSData->pDLS)
1727     {
1728 
1729         /* if local data was found convert it */
1730         if (art.values[PARAM_MODIFIED] == EAS_TRUE)
1731         {
1732             Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount);
1733             artIndex = (EAS_U16) pDLSData->artCount;
1734         }
1735 
1736         /* parse region header */
1737         if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS)
1738             return result;
1739 
1740         /* parse wsmp chunk, copying parameters from original first */
1741         if (wsmpPos)
1742         {
1743             EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp));
1744             if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS)
1745                 return result;
1746 
1747             pWsmp = &wsmp;
1748         }
1749 
1750         Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp);
1751 
1752         /* ensure loopStart and loopEnd fall in the range */
1753         if (pWsmp->loopLength != 0)
1754         {
1755             EAS_U32 sampleLen = pDLSData->pDLS->pDLSSampleLen[waveIndex];
1756             if (sampleLen < sizeof(EAS_SAMPLE)
1757                 || (pWsmp->loopStart + pWsmp->loopLength) * sizeof(EAS_SAMPLE) > sampleLen - sizeof(EAS_SAMPLE))
1758             {
1759                 return EAS_FAILURE;
1760             }
1761         }
1762     }
1763 
1764     /* if local articulation, bump count */
1765     if (art.values[PARAM_MODIFIED])
1766         pDLSData->artCount++;
1767 
1768     /* increment region count */
1769     pDLSData->regionCount++;
1770     return EAS_SUCCESS;
1771 }
1772 
1773 /*----------------------------------------------------------------------------
1774  * Parse_rgnh ()
1775  *----------------------------------------------------------------------------
1776  * Purpose:
1777  *
1778  *
1779  * Inputs:
1780  *
1781  *
1782  * Outputs:
1783  *
1784  *
1785  *----------------------------------------------------------------------------
1786 */
Parse_rgnh(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,S_DLS_REGION * pRgn)1787 static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn)
1788 {
1789     EAS_RESULT result;
1790     EAS_U16 lowKey;
1791     EAS_U16 highKey;
1792     EAS_U16 lowVel;
1793     EAS_U16 highVel;
1794     EAS_U16 optionFlags;
1795     EAS_U16 keyGroup;
1796 
1797     /* seek to start of chunk */
1798     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1799         return result;
1800 
1801     /* get the key range */
1802     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS)
1803         return result;
1804     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS)
1805         return result;
1806 
1807     /* check the range */
1808     if (lowKey > 127)
1809     {
1810         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ }
1811         lowKey = 127;
1812     }
1813     if (highKey > 127)
1814     {
1815         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ }
1816         highKey = 127;
1817     }
1818 
1819     /* get the velocity range */
1820     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS)
1821         return result;
1822     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS)
1823         return result;
1824 
1825     /* check the range */
1826     if (lowVel > 127)
1827     {
1828         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ }
1829         lowVel = 127;
1830     }
1831     if (highVel > 127)
1832     {
1833         { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ }
1834         highVel = 127;
1835     }
1836 
1837     /* get the option flags */
1838     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS)
1839         return result;
1840 
1841     /* get the key group */
1842     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS)
1843         return result;
1844 
1845     /* save the key range and key group */
1846     pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey;
1847     pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey;
1848 
1849     /*lint -e{734} keyGroup will always be from 0-15 */
1850     pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8;
1851     pRgn->velLow = (EAS_U8) lowVel;
1852     pRgn->velHigh = (EAS_U8) highVel;
1853     if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE)
1854         pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE;
1855 
1856     return EAS_SUCCESS;
1857 }
1858 
1859 /*----------------------------------------------------------------------------
1860  * Parse_lart ()
1861  *----------------------------------------------------------------------------
1862  * Purpose:
1863  *
1864  *
1865  * Inputs:
1866  *
1867  *
1868  * Outputs:
1869  *
1870  *
1871  *----------------------------------------------------------------------------
1872 */
Parse_lart(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_I32 size,S_DLS_ART_VALUES * pArt)1873 static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt)
1874 {
1875     EAS_RESULT result;
1876     EAS_U32 temp;
1877     EAS_I32 endChunk;
1878     EAS_I32 chunkPos;
1879     EAS_I32 art1Pos;
1880     EAS_I32 art2Pos;
1881 
1882     /* seek to start of chunk */
1883     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1884         return result;
1885 
1886     /* no articulation chunks yet */
1887     art1Pos = art2Pos = 0;
1888 
1889     /* read to end of chunk */
1890     endChunk = pos + size;
1891     while (pos < endChunk)
1892     {
1893         chunkPos = pos;
1894 
1895         /* get the next chunk type */
1896         if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
1897             return result;
1898 
1899         /* parse useful chunks */
1900         switch (temp)
1901         {
1902             case CHUNK_CDL:
1903                 if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
1904                     return result;
1905 
1906                 /* if conditional chunk evaluates false, skip this list */
1907                 if (!temp)
1908                     return EAS_SUCCESS;
1909                 break;
1910 
1911             case CHUNK_ART1:
1912                 art1Pos = chunkPos + 8;
1913                 break;
1914 
1915             case CHUNK_ART2:
1916                 art2Pos = chunkPos + 8;
1917                 break;
1918 
1919             default:
1920                 break;
1921 
1922         }
1923     }
1924 
1925     if (art1Pos)
1926     {
1927         if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS)
1928             return result;
1929     }
1930 
1931     if (art2Pos)
1932     {
1933         if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS)
1934             return result;
1935     }
1936 
1937     return EAS_SUCCESS;
1938 }
1939 
1940 /*----------------------------------------------------------------------------
1941  * Parse_art()
1942  *----------------------------------------------------------------------------
1943  * Purpose:
1944  *
1945  *
1946  * Inputs:
1947  *
1948  *
1949  * Outputs:
1950  *
1951  *
1952  *----------------------------------------------------------------------------
1953 */
Parse_art(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,S_DLS_ART_VALUES * pArt)1954 static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt)
1955 {
1956     EAS_RESULT result;
1957     EAS_U32 structSize;
1958     EAS_U32 numConnections;
1959     EAS_U16 source;
1960     EAS_U16 control;
1961     EAS_U16 destination;
1962     EAS_U16 transform;
1963     EAS_I32 scale;
1964     EAS_INT i;
1965 
1966     /* seek to start of data */
1967     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1968         return result;
1969 
1970     /* get the structure size */
1971     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS)
1972         return result;
1973     pos += (EAS_I32) structSize;
1974 
1975     /* get the number of connections */
1976     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS)
1977         return result;
1978 
1979     /* skip to start of connections */
1980     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
1981         return result;
1982 
1983     while (numConnections--)
1984     {
1985 
1986         /* read the connection data */
1987         if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS)
1988             return result;
1989         if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS)
1990             return result;
1991         if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS)
1992             return result;
1993         if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS)
1994             return result;
1995         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS)
1996             return result;
1997 
1998         /* look up the connection */
1999         for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++)
2000         {
2001             if ((connTable[i].source == source) &&
2002                 (connTable[i].destination == destination) &&
2003                 (connTable[i].control == control))
2004             {
2005                 /*lint -e{704} use shift for performance */
2006                 pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16);
2007                 pArt->values[PARAM_MODIFIED] = EAS_TRUE;
2008                 break;
2009             }
2010         }
2011         if (i == PARAM_TABLE_SIZE)
2012             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ }
2013     }
2014 
2015     return EAS_SUCCESS;
2016 }
2017 
2018 /*----------------------------------------------------------------------------
2019  * Parse_wlnk ()
2020  *----------------------------------------------------------------------------
2021  * Purpose:
2022  *
2023  *
2024  * Inputs:
2025  *
2026  *
2027  * Outputs:
2028  *
2029  *
2030  *----------------------------------------------------------------------------
2031 */
Parse_wlnk(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 pos,EAS_U32 * pWaveIndex)2032 static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex)
2033 {
2034     EAS_RESULT result;
2035 
2036     /* we only care about the the index */
2037     if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS)
2038         return result;
2039 
2040     /* read the index */
2041     return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE);
2042 }
2043 
2044 /*----------------------------------------------------------------------------
2045  * PopcdlStack ()
2046  *----------------------------------------------------------------------------
2047  * Purpose:
2048  *
2049  *
2050  * Inputs:
2051  *
2052  *
2053  * Outputs:
2054  *
2055  *
2056  *----------------------------------------------------------------------------
2057 */
PopcdlStack(EAS_U32 * pStack,EAS_INT * pStackPtr,EAS_U32 * pValue)2058 static EAS_RESULT PopcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 *pValue)
2059 {
2060 
2061     /* stack underflow, cdl block has an errorr */
2062     if (*pStackPtr < 0)
2063         return EAS_ERROR_FILE_FORMAT;
2064 
2065     /* pop the value off the stack */
2066     *pValue = pStack[*pStackPtr];
2067     *pStackPtr = *pStackPtr - 1;
2068     return EAS_SUCCESS;
2069 }
2070 
2071 /*----------------------------------------------------------------------------
2072  * PushcdlStack ()
2073  *----------------------------------------------------------------------------
2074  * Purpose:
2075  *
2076  *
2077  * Inputs:
2078  *
2079  *
2080  * Outputs:
2081  *
2082  *
2083  *----------------------------------------------------------------------------
2084 */
PushcdlStack(EAS_U32 * pStack,EAS_INT * pStackPtr,EAS_U32 value)2085 static EAS_RESULT PushcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 value)
2086 {
2087 
2088     /* stack overflow, return an error */
2089     if (*pStackPtr >= CDL_STACK_SIZE)
2090         return EAS_ERROR_FILE_FORMAT;
2091 
2092     /* push the value onto the stack */
2093     *pStackPtr = *pStackPtr + 1;
2094     pStack[*pStackPtr] = value;
2095     return EAS_SUCCESS;
2096 }
2097 
2098 /*----------------------------------------------------------------------------
2099  * QueryGUID ()
2100  *----------------------------------------------------------------------------
2101  * Purpose:
2102  *
2103  *
2104  * Inputs:
2105  *
2106  *
2107  * Outputs:
2108  *
2109  *
2110  *----------------------------------------------------------------------------
2111 */
QueryGUID(const DLSID * pGUID,EAS_U32 * pValue)2112 static EAS_BOOL QueryGUID (const DLSID *pGUID, EAS_U32 *pValue)
2113 {
2114 
2115     /* assume false */
2116     *pValue = 0;
2117     if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0)
2118     {
2119         *pValue = 0xffffffff;
2120         return EAS_TRUE;
2121     }
2122 
2123     if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0)
2124         return EAS_TRUE;
2125 
2126     if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0)
2127         return EAS_TRUE;
2128 
2129     if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0)
2130     {
2131         *pValue = 0xffffffff;
2132         return EAS_TRUE;
2133     }
2134 
2135     if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0)
2136         return EAS_TRUE;
2137 
2138     if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0)
2139     {
2140         *pValue = MAX_DLS_MEMORY;
2141         return EAS_TRUE;
2142     }
2143 
2144     if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0)
2145     {
2146         *pValue = 0x0000013A;
2147         return EAS_TRUE;
2148     }
2149 
2150     if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0)
2151     {
2152         *pValue = LIB_VERSION;
2153         return EAS_TRUE;
2154     }
2155 
2156     if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0)
2157     {
2158         *pValue = (EAS_U32) outputSampleRate;
2159         return EAS_TRUE;
2160     }
2161 
2162     /* unrecognized DLSID */
2163     return EAS_FALSE;
2164 }
2165 
2166 /*----------------------------------------------------------------------------
2167  * ReadDLSID ()
2168  *----------------------------------------------------------------------------
2169  * Purpose:
2170  * Reads a DLSID in a manner that is not sensitive to processor endian-ness
2171  *
2172  * Inputs:
2173  *
2174  *
2175  * Outputs:
2176  *
2177  *
2178  *----------------------------------------------------------------------------
2179 */
ReadDLSID(SDLS_SYNTHESIZER_DATA * pDLSData,DLSID * pDLSID)2180 static EAS_RESULT ReadDLSID (SDLS_SYNTHESIZER_DATA *pDLSData, DLSID *pDLSID)
2181 {
2182     EAS_RESULT result;
2183     EAS_I32 n;
2184 
2185     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS)
2186         return result;
2187     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS)
2188         return result;
2189     if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS)
2190         return result;
2191     return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n);
2192 }
2193 
2194 /*----------------------------------------------------------------------------
2195  * Parse_cdl ()
2196  *----------------------------------------------------------------------------
2197  * Purpose:
2198  *
2199  *
2200  * Inputs:
2201  *
2202  *
2203  * Outputs:
2204  *
2205  *
2206  *----------------------------------------------------------------------------
2207 */
Parse_cdl(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_I32 size,EAS_U32 * pValue)2208 static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue)
2209 {
2210     EAS_RESULT result;
2211     EAS_U32 stack[CDL_STACK_SIZE];
2212     EAS_U16 opcode;
2213     EAS_INT stackPtr;
2214     EAS_U32 x, y;
2215     DLSID dlsid;
2216 
2217     stackPtr = -1;
2218     *pValue = 0;
2219     x = 0;
2220     while (size)
2221     {
2222         /* read the opcode */
2223         if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS)
2224             return result;
2225 
2226         /* handle binary opcodes */
2227         if (opcode <= DLS_CDL_EQ)
2228         {
2229             /* pop X and Y */
2230             if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
2231                 return result;
2232             if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS)
2233                 return result;
2234             switch (opcode)
2235             {
2236                 case DLS_CDL_AND:
2237                     x = x & y;
2238                     break;
2239                 case DLS_CDL_OR:
2240                     x = x | y;
2241                     break;
2242                 case DLS_CDL_XOR:
2243                     x = x ^ y;
2244                     break;
2245                 case DLS_CDL_ADD:
2246                     x = x + y;
2247                     break;
2248                 case DLS_CDL_SUBTRACT:
2249                     x = x - y;
2250                     break;
2251                 case DLS_CDL_MULTIPLY:
2252                     x = x * y;
2253                     break;
2254                 case DLS_CDL_DIVIDE:
2255                     if (!y)
2256                         return EAS_ERROR_FILE_FORMAT;
2257                     x = x / y;
2258                     break;
2259                 case DLS_CDL_LOGICAL_AND:
2260                     x = (x && y);
2261                     break;
2262                 case DLS_CDL_LOGICAL_OR:
2263                     x = (x || y);
2264                     break;
2265                 case DLS_CDL_LT:
2266                     x = (x < y);
2267                     break;
2268                 case DLS_CDL_LE:
2269                     x = (x <= y);
2270                     break;
2271                 case DLS_CDL_GT:
2272                     x = (x > y);
2273                     break;
2274                 case DLS_CDL_GE:
2275                     x = (x >= y);
2276                     break;
2277                 case DLS_CDL_EQ:
2278                     x = (x == y);
2279                     break;
2280                 default:
2281                     break;
2282             }
2283         }
2284 
2285         else if (opcode == DLS_CDL_NOT)
2286         {
2287             if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
2288                 return result;
2289             x = !x;
2290         }
2291 
2292         else if (opcode == DLS_CDL_CONST)
2293         {
2294             if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS)
2295                 return result;
2296         }
2297 
2298         else if (opcode == DLS_CDL_QUERY)
2299         {
2300             if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
2301                 return result;
2302             QueryGUID(&dlsid, &x);
2303         }
2304 
2305         else if (opcode == DLS_CDL_QUERYSUPPORTED)
2306         {
2307             if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
2308                 return result;
2309             x = QueryGUID(&dlsid, &y);
2310         }
2311         else
2312             { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ }
2313 
2314         /* push the result on the stack */
2315         if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS)
2316             return result;
2317     }
2318 
2319     /* pop the last result off the stack */
2320     return PopcdlStack(stack, &stackPtr, pValue);
2321 }
2322 
2323 /*----------------------------------------------------------------------------
2324  * Convert_rgn()
2325  *----------------------------------------------------------------------------
2326  * Purpose:
2327  * Convert region data from DLS to EAS
2328  *
2329  * Inputs:
2330  *
2331  *
2332  * Outputs:
2333  *
2334  *
2335  *----------------------------------------------------------------------------
2336 */
Convert_rgn(SDLS_SYNTHESIZER_DATA * pDLSData,EAS_U16 regionIndex,EAS_U16 artIndex,EAS_U16 waveIndex,S_WSMP_DATA * pWsmp)2337 static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp)
2338 {
2339     S_DLS_REGION *pRgn;
2340 
2341     /* setup pointers to data structures */
2342     pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex];
2343 
2344     /* intiailize indices */
2345     pRgn->wtRegion.artIndex = artIndex;
2346     pRgn->wtRegion.waveIndex = waveIndex;
2347 
2348     /* convert region data */
2349     /*lint -e{704} use shift for performance */
2350     pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16);
2351     pRgn->wtRegion.loopStart = pWsmp->loopStart;
2352     pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength);
2353     pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate);
2354     if (pWsmp->loopLength != 0)
2355         pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED;
2356 }
2357 
2358 /*----------------------------------------------------------------------------
2359  * Convert_art()
2360  *----------------------------------------------------------------------------
2361  * Purpose:
2362  * Convert articulation data from DLS to EAS
2363  *
2364  * Inputs:
2365  *
2366  *
2367  * Outputs:
2368  *
2369  *
2370  *----------------------------------------------------------------------------
2371 */
Convert_art(SDLS_SYNTHESIZER_DATA * pDLSData,const S_DLS_ART_VALUES * pDLSArt,EAS_U16 artIndex)2372 static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt,  EAS_U16 artIndex)
2373 {
2374     S_DLS_ARTICULATION *pArt;
2375 
2376     /* setup pointers to data structures */
2377     pArt = &pDLSData->pDLS->pDLSArticulations[artIndex];
2378 
2379     /* LFO parameters */
2380     pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]);
2381     pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]);
2382     pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]);
2383     pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]);
2384 
2385     /* EG1 parameters */
2386     pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]);
2387     pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK];
2388     pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD];
2389     pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY];
2390     pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]);
2391     pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]);
2392     pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK];
2393     pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY];
2394     pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD];
2395     pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]);
2396 
2397     /* EG2 parameters */
2398     pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]);
2399     pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK];
2400     pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD];
2401     pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY];
2402     pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]);
2403     pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]);
2404     pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK];
2405     pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY];
2406     pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD];
2407 
2408     /* filter parameters */
2409     pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC];
2410     pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]);
2411     pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC];
2412     pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC];
2413     pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC];
2414     pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC];
2415     pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC];
2416     pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC];
2417 
2418     /* gain parameters */
2419     pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN];
2420     pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN];
2421     pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN];
2422 
2423     /* pitch parameters */
2424     pArt->tuning = pDLSArt->values[PARAM_TUNING];
2425     pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH];
2426     pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH];
2427     pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH];
2428     pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH];
2429     pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH];
2430     pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH];
2431     pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH];
2432     pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH];
2433 
2434     /* output parameters */
2435     pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]);
2436 
2437     if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0)
2438         pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE;
2439 
2440 #ifdef _REVERB
2441     pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND];
2442     pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND];
2443 #endif
2444 
2445 #ifdef _CHORUS
2446     pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND];
2447     pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND];
2448 #endif
2449 }
2450 
2451 /*----------------------------------------------------------------------------
2452  * ConvertSampleRate()
2453  *----------------------------------------------------------------------------
2454  * Purpose:
2455  *
2456  * Inputs:
2457  *
2458  * Outputs:
2459  *
2460  * Side Effects:
2461  *----------------------------------------------------------------------------
2462 */
ConvertSampleRate(EAS_U32 sampleRate)2463 static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate)
2464 {
2465     return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0));
2466 }
2467 
2468 /*----------------------------------------------------------------------------
2469  * ConvertSustainEG2()
2470  *----------------------------------------------------------------------------
2471  * Convert sustain level to pitch/Fc multipler for EG2
2472  *----------------------------------------------------------------------------
2473 */
ConvertSustain(EAS_I32 sustain)2474 static EAS_I16 ConvertSustain (EAS_I32 sustain)
2475 {
2476     /* check for sustain level of zero */
2477     if (sustain == 0)
2478         return 0;
2479 
2480     /* convert to log2 factor */
2481     /*lint -e{704} use shift for performance */
2482     sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15;
2483 
2484     if (sustain > SYNTH_FULL_SCALE_EG1_GAIN)
2485         return SYNTH_FULL_SCALE_EG1_GAIN;
2486     return (EAS_I16) sustain;
2487 }
2488 
2489 /*----------------------------------------------------------------------------
2490  * ConvertDelay ()
2491  *----------------------------------------------------------------------------
2492  * Converts timecents to frame count. Used for LFO and envelope
2493  * delay times.
2494  *----------------------------------------------------------------------------
2495 */
ConvertDelay(EAS_I32 timeCents)2496 EAS_I16 ConvertDelay (EAS_I32 timeCents)
2497 {
2498     EAS_I32 temp;
2499 
2500     if (timeCents == ZERO_TIME_IN_CENTS)
2501         return 0;
2502 
2503     /* divide time by secs per frame to get number of frames */
2504     temp = timeCents - dlsRateConvert;
2505 
2506     /* convert from time cents to 10-bit fraction */
2507     temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
2508 
2509     /* convert to frame count */
2510     temp = EAS_LogToLinear16(temp - (15 << 10));
2511 
2512     if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
2513         return (EAS_I16) temp;
2514     return SYNTH_FULL_SCALE_EG1_GAIN;
2515 }
2516 
2517 /*----------------------------------------------------------------------------
2518  * ConvertRate ()
2519  *----------------------------------------------------------------------------
2520  * Convert timecents to rate
2521  *----------------------------------------------------------------------------
2522 */
ConvertRate(EAS_I32 timeCents)2523 EAS_I16 ConvertRate (EAS_I32 timeCents)
2524 {
2525     EAS_I32 temp;
2526 
2527     if (timeCents == ZERO_TIME_IN_CENTS)
2528         return SYNTH_FULL_SCALE_EG1_GAIN;
2529 
2530     /* divide frame rate by time in log domain to get rate */
2531     temp = dlsRateConvert - timeCents;
2532 
2533 #if 1
2534     temp = EAS_Calculate2toX(temp);
2535 #else
2536     /* convert from time cents to 10-bit fraction */
2537     temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);
2538 
2539     /* convert to rate */
2540     temp = EAS_LogToLinear16(temp);
2541 #endif
2542 
2543     if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
2544         return (EAS_I16) temp;
2545     return SYNTH_FULL_SCALE_EG1_GAIN;
2546 }
2547 
2548 
2549 /*----------------------------------------------------------------------------
2550  * ConvertLFOPhaseIncrement()
2551  *----------------------------------------------------------------------------
2552  * Purpose:
2553  *
2554  * Inputs:
2555  *
2556  * Outputs:
2557  *
2558  * Side Effects:
2559  *----------------------------------------------------------------------------
2560 */
ConvertLFOPhaseIncrement(EAS_I32 pitchCents)2561 static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents)
2562 {
2563 
2564     /* check range */
2565     if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS)
2566         pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS;
2567     if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS)
2568         pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS;
2569 
2570     /* double the rate and divide by frame rate by subtracting in log domain */
2571     pitchCents = pitchCents - dlsLFOFrequencyConvert;
2572 
2573     /* convert to phase increment */
2574     return (EAS_I16) EAS_Calculate2toX(pitchCents);
2575 }
2576 
2577 /*----------------------------------------------------------------------------
2578  * ConvertPan()
2579  *----------------------------------------------------------------------------
2580  * Purpose:
2581  *
2582  * Inputs:
2583  *
2584  * Outputs:
2585  *
2586  * Side Effects:
2587  *----------------------------------------------------------------------------
2588 */
ConvertPan(EAS_I32 pan)2589 static EAS_I8 ConvertPan (EAS_I32 pan)
2590 {
2591 
2592     /* multiply by conversion factor */
2593     pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan);
2594     if (pan < MIN_PAN_VALUE)
2595         return MIN_PAN_VALUE;
2596     if (pan > MAX_PAN_VALUE)
2597         return MAX_PAN_VALUE;
2598     return (EAS_I8) pan;
2599 }
2600 
2601 /*----------------------------------------------------------------------------
2602  * ConvertQ()
2603  *----------------------------------------------------------------------------
2604  * Convert the DLS filter resonance to an index value used by the synth
2605  * that accesses tables of coefficients based on the Q.
2606  *----------------------------------------------------------------------------
2607 */
ConvertQ(EAS_I32 q)2608 static EAS_U8 ConvertQ (EAS_I32 q)
2609 {
2610 
2611     /* apply limits */
2612     if (q <= 0)
2613         return 0;
2614 
2615     /* convert to table index */
2616     /*lint -e{704} use shift for performance */
2617     q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15;
2618 
2619     /* apply upper limit */
2620     if (q >= FILTER_RESONANCE_NUM_ENTRIES)
2621         q = FILTER_RESONANCE_NUM_ENTRIES - 1;
2622     return (EAS_U8) q;
2623 }
2624 
2625 #ifdef _DEBUG_DLS
2626 /*----------------------------------------------------------------------------
2627  * DumpDLS()
2628  *----------------------------------------------------------------------------
2629 */
DumpDLS(S_EAS * pEAS)2630 static void DumpDLS (S_EAS *pEAS)
2631 {
2632     S_DLS_ARTICULATION *pArt;
2633     S_DLS_REGION *pRegion;
2634     EAS_INT i;
2635     EAS_INT j;
2636 
2637     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms);
2638     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions);
2639     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations);
2640     EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples);
2641 
2642     /* dump the instruments */
2643     for (i = 0; i < pEAS->numPrograms; i++)
2644     {
2645         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 ,
2646                 pEAS->pPrograms[i].locale >> 16,
2647                 (pEAS->pPrograms[i].locale >> 8) & 0x7f,
2648                 pEAS->pPrograms[i].locale & 0x7f);
2649 
2650         for (j = pEAS->pPrograms[i].regionIndex; ; j++)
2651         {
2652             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j);
2653             pRegion = &pEAS->pWTRegions[j];
2654             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain);
2655             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh);
2656             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags);
2657             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart);
2658             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd);
2659             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning);
2660             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex);
2661             EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex);
2662 
2663             if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
2664                 break;
2665         }
2666 
2667     }
2668 
2669     /* dump the articulation data */
2670     for (i = 0; i < pEAS->numDLSArticulations; i++)
2671     {
2672         /* articulation data */
2673         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i);
2674         pArt = &pEAS->pDLSArticulations[i];
2675         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth);
2676         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth);
2677         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency);
2678         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance);
2679         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth);
2680         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime);
2681         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency);
2682         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth);
2683         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan);
2684 
2685         /* EG1 data */
2686         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack);
2687         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay);
2688         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain);
2689         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease);
2690 
2691         /* EG2 data */
2692         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack);
2693         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay);
2694         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain);
2695         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease);
2696 
2697     }
2698 
2699     /* dump the waves */
2700     for (i = 0; i < pEAS->numSamples; i++)
2701     {
2702         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i);
2703         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]);
2704         EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]);
2705     }
2706 
2707 }
2708 #endif
2709 
2710