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