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