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