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