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