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