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