Home | History | Annotate | Download | only in lib_src
      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, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
   1121         return result;
   1122 
   1123     /* sample loops */
   1124     if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, 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, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
   1140             return result;
   1141 
   1142         /* get loop type */
   1143         if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, 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, &ltemp, 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, &regionCount, &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