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