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