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