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