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