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