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