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