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