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