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