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