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