Commit message: None
CVE: CVE-2015-3836
CWE: CWE-189
Vulnerability description: The Parse_wave function in arm-wt-22k/lib_src/eas_mdls.c in the Sonivox DLS-to-EAS converter in Android before 5.1.1 LMY48I does not reject a negative value for a certain size field, which allows remote attackers to execute arbitrary code or cause a denial of service (buffer overflow) via crafted XMF data, aka internal bug 21132860.

Project: Android

EAS_I16 ConvertDelay (EAS_I32 timeCents)
{
    EAS_I32 temp;

 if (timeCents == ZERO_TIME_IN_CENTS)
 return 0;

 /* divide time by secs per frame to get number of frames */
    temp = timeCents - dlsRateConvert;

 /* convert from time cents to 10-bit fraction */
    temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);

 /* convert to frame count */
    temp = EAS_LogToLinear16(temp - (15 << 10));

 if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
 return (EAS_I16) temp;
 return SYNTH_FULL_SCALE_EG1_GAIN;
}

Project: Android

static EAS_I16 ConvertLFOPhaseIncrement (EAS_I32 pitchCents)
{

 /* check range */
 if (pitchCents > MAX_LFO_FREQUENCY_IN_PITCHCENTS)
        pitchCents = MAX_LFO_FREQUENCY_IN_PITCHCENTS;
 if (pitchCents < MIN_LFO_FREQUENCY_IN_PITCHCENTS)
        pitchCents = MIN_LFO_FREQUENCY_IN_PITCHCENTS;

 /* double the rate and divide by frame rate by subtracting in log domain */
    pitchCents = pitchCents - dlsLFOFrequencyConvert;

 /* convert to phase increment */
 return (EAS_I16) EAS_Calculate2toX(pitchCents);
}

Project: Android

static EAS_I8 ConvertPan (EAS_I32 pan)
{

 /* multiply by conversion factor */
    pan = FMUL_15x15 (PAN_CONVERSION_FACTOR, pan);
 if (pan < MIN_PAN_VALUE)
 return MIN_PAN_VALUE;
 if (pan > MAX_PAN_VALUE)
 return MAX_PAN_VALUE;
 return (EAS_I8) pan;
}

Project: Android

static EAS_U8 ConvertQ (EAS_I32 q)
{

 /* apply limits */
 if (q <= 0)
 return 0;

 /* convert to table index */
 /*lint -e{704} use shift for performance */
    q = (FILTER_Q_CONVERSION_FACTOR * q + 0x4000) >> 15;

 /* apply upper limit */
 if (q >= FILTER_RESONANCE_NUM_ENTRIES)
        q = FILTER_RESONANCE_NUM_ENTRIES - 1;
 return (EAS_U8) q;
}

Project: Android

EAS_I16 ConvertRate (EAS_I32 timeCents)
{
    EAS_I32 temp;

 if (timeCents == ZERO_TIME_IN_CENTS)
 return SYNTH_FULL_SCALE_EG1_GAIN;

 /* divide frame rate by time in log domain to get rate */
    temp = dlsRateConvert - timeCents;

#if 1
    temp = EAS_Calculate2toX(temp);
#else
 /* convert from time cents to 10-bit fraction */
    temp = FMUL_15x15(temp, TIME_CENTS_TO_LOG2);

 /* convert to rate */
    temp = EAS_LogToLinear16(temp);
#endif

 if (temp < SYNTH_FULL_SCALE_EG1_GAIN)
 return (EAS_I16) temp;
 return SYNTH_FULL_SCALE_EG1_GAIN;
}

Project: Android

static EAS_I16 ConvertSampleRate (EAS_U32 sampleRate)
{
 return (EAS_I16) (1200.0 * log10((double) sampleRate / (double) outputSampleRate) / log10(2.0));
}

Project: Android

static EAS_I16 ConvertSustain (EAS_I32 sustain)
{
 /* check for sustain level of zero */
 if (sustain == 0)
 return 0;

 /* convert to log2 factor */
 /*lint -e{704} use shift for performance */
    sustain = (sustain * SUSTAIN_LINEAR_CONVERSION_FACTOR) >> 15;

 if (sustain > SYNTH_FULL_SCALE_EG1_GAIN)
 return SYNTH_FULL_SCALE_EG1_GAIN;
 return (EAS_I16) sustain;
}

Project: Android

static void Convert_art (SDLS_SYNTHESIZER_DATA *pDLSData, const S_DLS_ART_VALUES *pDLSArt,  EAS_U16 artIndex)
{
    S_DLS_ARTICULATION *pArt;

 /* setup pointers to data structures */
    pArt = &pDLSData->pDLS->pDLSArticulations[artIndex];

 /* LFO parameters */
    pArt->modLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_MOD_LFO_FREQ]);
    pArt->modLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_MOD_LFO_DELAY]);
    pArt->vibLFO.lfoFreq = ConvertLFOPhaseIncrement(pDLSArt->values[PARAM_VIB_LFO_FREQ]);
    pArt->vibLFO.lfoDelay = -ConvertDelay(pDLSArt->values[PARAM_VIB_LFO_DELAY]);

 /* EG1 parameters */
    pArt->eg1.delayTime = ConvertDelay(pDLSArt->values[PARAM_VOL_EG_DELAY]);
    pArt->eg1.attackTime = pDLSArt->values[PARAM_VOL_EG_ATTACK];
    pArt->eg1.holdTime = pDLSArt->values[PARAM_VOL_EG_HOLD];
    pArt->eg1.decayTime = pDLSArt->values[PARAM_VOL_EG_DECAY];
    pArt->eg1.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_VOL_EG_SUSTAIN]);
    pArt->eg1.releaseTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_RELEASE]);
    pArt->eg1.velToAttack = pDLSArt->values[PARAM_VOL_EG_VEL_TO_ATTACK];
    pArt->eg1.keyNumToDecay = pDLSArt->values[PARAM_VOL_EG_KEY_TO_DECAY];
    pArt->eg1.keyNumToHold = pDLSArt->values[PARAM_VOL_EG_KEY_TO_HOLD];
    pArt->eg1ShutdownTime = ConvertRate(pDLSArt->values[PARAM_VOL_EG_SHUTDOWN]);

 /* EG2 parameters */
    pArt->eg2.delayTime = ConvertDelay(pDLSArt->values[PARAM_MOD_EG_DELAY]);
    pArt->eg2.attackTime = pDLSArt->values[PARAM_MOD_EG_ATTACK];
    pArt->eg2.holdTime = pDLSArt->values[PARAM_MOD_EG_HOLD];
    pArt->eg2.decayTime = pDLSArt->values[PARAM_MOD_EG_DECAY];
    pArt->eg2.sustainLevel = ConvertSustain(pDLSArt->values[PARAM_MOD_EG_SUSTAIN]);
    pArt->eg2.releaseTime = ConvertRate(pDLSArt->values[PARAM_MOD_EG_RELEASE]);
    pArt->eg2.velToAttack = pDLSArt->values[PARAM_MOD_EG_VEL_TO_ATTACK];
    pArt->eg2.keyNumToDecay = pDLSArt->values[PARAM_MOD_EG_KEY_TO_DECAY];
    pArt->eg2.keyNumToHold = pDLSArt->values[PARAM_MOD_EG_KEY_TO_HOLD];

 /* filter parameters */
    pArt->filterCutoff = pDLSArt->values[PARAM_INITIAL_FC];
    pArt->filterQandFlags = ConvertQ(pDLSArt->values[PARAM_INITIAL_Q]);
    pArt->modLFOToFc = pDLSArt->values[PARAM_MOD_LFO_TO_FC];
    pArt->modLFOCC1ToFc = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_FC];
    pArt->modLFOChanPressToFc = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_FC];
    pArt->eg2ToFc = pDLSArt->values[PARAM_MOD_EG_TO_FC];
    pArt->velToFc = pDLSArt->values[PARAM_VEL_TO_FC];
    pArt->keyNumToFc = pDLSArt->values[PARAM_KEYNUM_TO_FC];

 /* gain parameters */
    pArt->modLFOToGain = pDLSArt->values[PARAM_MOD_LFO_TO_GAIN];
    pArt->modLFOCC1ToGain = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_GAIN];
    pArt->modLFOChanPressToGain = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_GAIN];

 /* pitch parameters */
    pArt->tuning = pDLSArt->values[PARAM_TUNING];
    pArt->keyNumToPitch = pDLSArt->values[PARAM_KEYNUM_TO_PITCH];
    pArt->vibLFOToPitch = pDLSArt->values[PARAM_VIB_LFO_TO_PITCH];
    pArt->vibLFOCC1ToPitch = pDLSArt->values[PARAM_VIB_LFO_CC1_TO_PITCH];
    pArt->vibLFOChanPressToPitch = pDLSArt->values[PARAM_VIB_LFO_CHAN_PRESS_TO_PITCH];
    pArt->modLFOToPitch = pDLSArt->values[PARAM_MOD_LFO_TO_PITCH];
    pArt->modLFOCC1ToPitch = pDLSArt->values[PARAM_MOD_LFO_CC1_TO_PITCH];
    pArt->modLFOChanPressToPitch = pDLSArt->values[PARAM_MOD_LFO_CHAN_PRESS_TO_PITCH];
    pArt->eg2ToPitch = pDLSArt->values[PARAM_MOD_EG_TO_PITCH];

 /* output parameters */
    pArt->pan = ConvertPan(pDLSArt->values[PARAM_DEFAULT_PAN]);

 if (pDLSArt->values[PARAM_VEL_TO_GAIN] != 0)
        pArt->filterQandFlags |= FLAG_DLS_VELOCITY_SENSITIVE;

#ifdef _REVERB
    pArt->reverbSend = pDLSArt->values[PARAM_DEFAULT_REVERB_SEND];
    pArt->cc91ToReverbSend = pDLSArt->values[PARAM_MIDI_CC91_TO_REVERB_SEND];
#endif

#ifdef _CHORUS
    pArt->chorusSend = pDLSArt->values[PARAM_DEFAULT_CHORUS_SEND];
    pArt->cc93ToChorusSend = pDLSArt->values[PARAM_MIDI_CC93_TO_CHORUS_SEND];
#endif
}

Project: Android

static void Convert_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_U16 regionIndex, EAS_U16 artIndex, EAS_U16 waveIndex, S_WSMP_DATA *pWsmp)
{
    S_DLS_REGION *pRgn;

 /* setup pointers to data structures */
    pRgn = &pDLSData->pDLS->pDLSRegions[regionIndex];

 /* intiailize indices */
    pRgn->wtRegion.artIndex = artIndex;
    pRgn->wtRegion.waveIndex = waveIndex;

 /* convert region data */
 /*lint -e{704} use shift for performance */
    pRgn->wtRegion.gain = (EAS_I16) (pWsmp->gain >> 16);
    pRgn->wtRegion.loopStart = pWsmp->loopStart;
    pRgn->wtRegion.loopEnd = (pWsmp->loopStart + pWsmp->loopLength);
    pRgn->wtRegion.tuning = pWsmp->fineTune -(pWsmp->unityNote * 100) + ConvertSampleRate(pWsmp->sampleRate);
 if (pWsmp->loopLength != 0)
        pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_IS_LOOPED;
}

Project: Android

void DLSAddRef (S_DLS *pDLS)
{
 if (pDLS)
        pDLS->refCount++;
}

Project: Android

static void DumpDLS (S_EAS *pEAS)
{
    S_DLS_ARTICULATION *pArt;
    S_DLS_REGION *pRegion;
    EAS_INT i;
    EAS_INT j;

    EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000022 , pEAS->numPrograms);
    EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000023 , pEAS->numWTRegions);
    EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000024 , pEAS->numDLSArticulations);
    EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000025 , pEAS->numSamples);

 /* dump the instruments */
 for (i = 0; i < pEAS->numPrograms; i++)
 {
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000026 ,
                pEAS->pPrograms[i].locale >> 16,
 (pEAS->pPrograms[i].locale >> 8) & 0x7f,
                pEAS->pPrograms[i].locale & 0x7f);

 for (j = pEAS->pPrograms[i].regionIndex; ; j++)
 {
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000027 , j);
            pRegion = &pEAS->pWTRegions[j];
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000028 , pRegion->gain);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000029 , pRegion->region.rangeLow, pRegion->region.rangeHigh);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002a , pRegion->region.keyGroupAndFlags);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002b , pRegion->loopStart);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002c , pRegion->loopEnd);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002d , pRegion->tuning);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002e , pRegion->artIndex);
            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000002f , pRegion->waveIndex);

 if (pRegion->region.keyGroupAndFlags & REGION_FLAG_LAST_REGION)
 break;
 }

 }

 /* dump the articulation data */
 for (i = 0; i < pEAS->numDLSArticulations; i++)
 {
 /* articulation data */
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000030 , i);
        pArt = &pEAS->pDLSArticulations[i];
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000031 , pArt->m_nEG2toFilterDepth);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000032 , pArt->m_nEG2toPitchDepth);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000033 , pArt->m_nFilterCutoffFrequency);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000034 , pArt->m_nFilterResonance);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000035 , pArt->m_nLFOAmplitudeDepth);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000036 , pArt->m_nLFODelayTime);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000037 , pArt->m_nLFOFrequency);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000038 , pArt->m_nLFOPitchDepth);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000039 , pArt->m_nPan);

 /* EG1 data */
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003a , pArt->m_sEG1.m_nAttack);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003b , pArt->m_sEG1.m_nDecay);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003c , pArt->m_sEG1.m_nSustain);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003d , pArt->m_sEG1.m_nRelease);

 /* EG2 data */
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003e , pArt->m_sEG2.m_nAttack);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x0000003f , pArt->m_sEG2.m_nDecay);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000040 , pArt->m_sEG2.m_nSustain);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000041 , pArt->m_sEG2.m_nRelease);

 }

 /* dump the waves */
 for (i = 0; i < pEAS->numSamples; i++)
 {
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000042 , i);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000043 , pEAS->pSampleLen[i]);
        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x19299ed4, 0x00000044 , pEAS->ppSamples[i]);
 }

}

Project: Android

static EAS_RESULT Parse_art (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_ART_VALUES *pArt)
{
    EAS_RESULT result;
    EAS_U32 structSize;
    EAS_U32 numConnections;
    EAS_U16 source;
    EAS_U16 control;
    EAS_U16 destination;
    EAS_U16 transform;
    EAS_I32 scale;
    EAS_INT i;

 /* seek to start of data */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* get the structure size */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &structSize, EAS_FALSE)) != EAS_SUCCESS)
 return result;
    pos += (EAS_I32) structSize;

 /* get the number of connections */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &numConnections, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* skip to start of connections */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 while (numConnections--)
 {

 /* read the connection data */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &source, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &control, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &destination, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &transform, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &scale, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* look up the connection */
 for (i = 0; i < (EAS_INT) ENTRIES_IN_CONN_TABLE; i++)
 {
 if ((connTable[i].source == source) &&
 (connTable[i].destination == destination) &&
 (connTable[i].control == control))
 {
 /*lint -e{704} use shift for performance */
                pArt->values[connTable[i].connection] = (EAS_I16) (scale >> 16);
                pArt->values[PARAM_MODIFIED] = EAS_TRUE;
 break;
 }
 }
 if (i == PARAM_TABLE_SIZE)
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "WARN: Unsupported parameter in DLS file\n"); */ }
 }

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_cdl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 size, EAS_U32 *pValue)
{
    EAS_RESULT result;
    EAS_U32 stack[CDL_STACK_SIZE];
    EAS_U16 opcode;
    EAS_INT stackPtr;
    EAS_U32 x, y;
    DLSID dlsid;

    stackPtr = -1;
 *pValue = 0;
    x = 0;
 while (size)
 {
 /* read the opcode */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &opcode, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* handle binary opcodes */
 if (opcode <= DLS_CDL_EQ)
 {
 /* pop X and Y */
 if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
 return result;
 if ((result = PopcdlStack(stack, &stackPtr, &y)) != EAS_SUCCESS)
 return result;
 switch (opcode)
 {
 case DLS_CDL_AND:
                    x = x & y;
 break;
 case DLS_CDL_OR:
                    x = x | y;
 break;
 case DLS_CDL_XOR:
                    x = x ^ y;
 break;
 case DLS_CDL_ADD:
                    x = x + y;
 break;
 case DLS_CDL_SUBTRACT:
                    x = x - y;
 break;
 case DLS_CDL_MULTIPLY:
                    x = x * y;
 break;
 case DLS_CDL_DIVIDE:
 if (!y)
 return EAS_ERROR_FILE_FORMAT;
                    x = x / y;
 break;
 case DLS_CDL_LOGICAL_AND:
                    x = (x && y);
 break;
 case DLS_CDL_LOGICAL_OR:
                    x = (x || y);
 break;
 case DLS_CDL_LT:
                    x = (x < y);
 break;
 case DLS_CDL_LE:
                    x = (x <= y);
 break;
 case DLS_CDL_GT:
                    x = (x > y);
 break;
 case DLS_CDL_GE:
                    x = (x >= y);
 break;
 case DLS_CDL_EQ:
                    x = (x == y);
 break;
 default:
 break;
 }
 }

 else if (opcode == DLS_CDL_NOT)
 {
 if ((result = PopcdlStack(stack, &stackPtr, &x)) != EAS_SUCCESS)
 return result;
            x = !x;
 }

 else if (opcode == DLS_CDL_CONST)
 {
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &x, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 }

 else if (opcode == DLS_CDL_QUERY)
 {
 if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
 return result;
 QueryGUID(&dlsid, &x);
 }

 else if (opcode == DLS_CDL_QUERYSUPPORTED)
 {
 if ((result = ReadDLSID(pDLSData, &dlsid)) != EAS_SUCCESS)
 return result;
            x = QueryGUID(&dlsid, &y);
 }
 else
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Unsupported opcode %d in DLS file\n", opcode); */ }

 /* push the result on the stack */
 if ((result = PushcdlStack(stack, &stackPtr, x)) != EAS_SUCCESS)
 return result;
 }

 /* pop the last result off the stack */
 return PopcdlStack(stack, &stackPtr, pValue);
}

Project: Android

static EAS_RESULT Parse_data (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_WSMP_DATA *pWsmp, EAS_SAMPLE *pSample)
{
    EAS_RESULT result;
    EAS_U8 convBuf[SAMPLE_CONVERT_CHUNK_SIZE];
    EAS_I32 count;
    EAS_I32 i;
    EAS_I8 *p;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* 8-bit samples in an 8-bit synth, just copy the data, and flip bit 7 */
    p = pSample;
 if (pWsmp->bitsPerSample == 8)
 {
 if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pSample, size, &count)) != EAS_SUCCESS)
 return result;
 for (i = 0; i < size; i++)
 /*lint -e{734} convert from unsigned to signed audio */
 *p++ ^= 0x80;
 }

 /* 16-bit samples, need to convert to 8-bit or ADPCM */
 else
 {

 while (size)
 {
            EAS_I8 *pInput;

 /* for undithered conversion, we're just copying the 8-bit data */
 if (pDLSData->bigEndian)
                pInput = (EAS_I8*) convBuf;
 else
                pInput = (EAS_I8*) convBuf + 1;

 /* read a small chunk of data and convert it */
            count = (size < SAMPLE_CONVERT_CHUNK_SIZE ? size : SAMPLE_CONVERT_CHUNK_SIZE);
 if ((result = EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, convBuf, count, &count)) != EAS_SUCCESS)
 return result;
            size -= count;
 /*lint -e{704} use shift for performance */
            count = count >> 1;

 while (count--)
 {
 *p++ = *pInput;
                pInput += 2;
 }
 }
 }

 /* for looped samples, copy the last sample to the end */
 if (pWsmp->loopLength)
        pSample[pWsmp->loopStart + pWsmp->loopLength] = pSample[pWsmp->loopStart];

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_fmt (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
{
    EAS_RESULT result;
    EAS_U16 wtemp;
    EAS_U32 ltemp;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* get format tag */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if (wtemp != WAVE_FORMAT_PCM)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS sample format %04x\n", wtemp); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 /* get number of channels */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if (wtemp != 1)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "No support for DLS multi-channel samples\n"); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 /* get sample rate */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->sampleRate, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* bytes/sec */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* block align */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* bits/sample */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->bitsPerSample, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 if ((p->bitsPerSample != 8) && (p->bitsPerSample != 16))
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Unsupported DLS bits-per-sample %d\n", p->bitsPerSample); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_ins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
{
    EAS_RESULT result;
    EAS_U32 temp;
    EAS_I32 chunkPos;
    EAS_I32 endChunk;
    EAS_I32 lrgnPos;
    EAS_I32 lrgnSize;
    EAS_I32 lartPos;
    EAS_I32 lartSize;
    EAS_I32 lar2Pos;
    EAS_I32 lar2Size;
    EAS_I32 inshPos;
    EAS_U32 regionCount;
    EAS_U32 locale;
    S_DLS_ART_VALUES art;
    S_PROGRAM *pProgram;
    EAS_U16 artIndex;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* no chunks yet */
    lrgnPos = lrgnSize = lartPos = lartSize = lar2Pos = lar2Size = inshPos = artIndex = 0;

 /* read to end of chunk */
    endChunk = pos + size;
 while (pos < endChunk)
 {
        chunkPos = pos;

 /* get the next chunk type */
 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
 return result;

 /* parse useful chunks */
 switch (temp)
 {
 case CHUNK_INSH:
                inshPos = chunkPos + 8;
 break;

 case CHUNK_LART:
                lartPos = chunkPos + 12;
                lartSize = size;
 break;

 case CHUNK_LAR2:
                lar2Pos = chunkPos + 12;
                lar2Size = size;
 break;

 case CHUNK_LRGN:
                lrgnPos = chunkPos + 12;
                lrgnSize = size;
 break;

 default:
 break;
 }
 }

 /* must have an lrgn to be useful */
 if (!lrgnPos)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no lrgn chunk\n"); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 /* must have an insh to be useful */
 if (!inshPos)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS ins chunk has no insh chunk\n"); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 /* parse the instrument header */
 if ((result = Parse_insh(pDLSData, inshPos, &regionCount, &locale)) != EAS_SUCCESS)
 return result;

 /* initialize and parse the global data first */
    EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
 if (lartPos)
 if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
 return result;
 if (lar2Pos)
 if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
 return result;

 if (art.values[PARAM_MODIFIED])
 {
        artIndex = (EAS_U16) pDLSData->artCount;
        pDLSData->artCount++;
 }

 /* convert data on second pass */
 if (pDLSData->pDLS)
 {

 if (art.values[PARAM_MODIFIED])
 Convert_art(pDLSData, &art, artIndex);

 /* setup pointers */
        pProgram = &pDLSData->pDLS->pDLSPrograms[pDLSData->instCount];

 /* initialize instrument */
        pProgram->locale = locale;
        pProgram->regionIndex = (EAS_U16) pDLSData->regionCount | FLAG_RGN_IDX_DLS_SYNTH;

 }

 /* parse the region data */
 if ((result = Parse_lrgn(pDLSData, lrgnPos, lrgnSize, artIndex, regionCount)) != EAS_SUCCESS)
 return result;

 /* bump instrument count */
    pDLSData->instCount++;
 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_insh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pRgnCount, EAS_U32 *pLocale)
{
    EAS_RESULT result;
    EAS_U32 bank;
    EAS_U32 program;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* get the region count and locale */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, pRgnCount, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &bank, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &program, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* verify the parameters are valid */
 if (bank & 0x7fff8080)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS bank number is out of range: %08lx\n", bank); */ }
        bank &= 0xff7f;
 }
 if (program > 127)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS program number is out of range: %08lx\n", program); */ }
        program &= 0x7f;
 }

 /* save the program number */
 *pLocale = (bank << 8) | program;
 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_lart (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, S_DLS_ART_VALUES *pArt)
{
    EAS_RESULT result;
    EAS_U32 temp;
    EAS_I32 endChunk;
    EAS_I32 chunkPos;
    EAS_I32 art1Pos;
    EAS_I32 art2Pos;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* no articulation chunks yet */
    art1Pos = art2Pos = 0;

 /* read to end of chunk */
    endChunk = pos + size;
 while (pos < endChunk)
 {
        chunkPos = pos;

 /* get the next chunk type */
 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
 return result;

 /* parse useful chunks */
 switch (temp)
 {
 case CHUNK_CDL:
 if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
 return result;

 /* if conditional chunk evaluates false, skip this list */
 if (!temp)
 return EAS_SUCCESS;
 break;

 case CHUNK_ART1:
                art1Pos = chunkPos + 8;
 break;

 case CHUNK_ART2:
                art2Pos = chunkPos + 8;
 break;

 default:
 break;

 }
 }

 if (art1Pos)
 {
 if ((result = Parse_art(pDLSData, art1Pos, pArt)) != EAS_SUCCESS)
 return result;
 }

 if (art2Pos)
 {
 if ((result = Parse_art(pDLSData, art2Pos, pArt)) != EAS_SUCCESS)
 return result;
 }

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_lins (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size)
{
    EAS_RESULT result;
    EAS_U32 temp;
    EAS_I32 endChunk;
    EAS_I32 chunkPos;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* read to end of chunk */
    endChunk = pos + size;
 while (pos < endChunk)
 {
        chunkPos = pos;

 /* get the next chunk type */
 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
 return result;

 /* only instrument chunks are useful */
 if (temp != CHUNK_INS)
 continue;

 if ((result = Parse_ins(pDLSData, chunkPos + 12, size)) != EAS_SUCCESS)
 return result;
 }

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_lrgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex, EAS_U32 numRegions)
{
    EAS_RESULT result;
    EAS_U32 temp;
    EAS_I32 chunkPos;
    EAS_I32 endChunk;
    EAS_U16 regionCount;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* read to end of chunk */
    regionCount = 0;
    endChunk = pos + size;
 while (pos < endChunk)
 {
        chunkPos = pos;

 /* get the next chunk type */
 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
 return result;

 if ((temp == CHUNK_RGN) || (temp == CHUNK_RGN2))
 {
 if (regionCount == numRegions)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS region count exceeded cRegions value in insh, extra region ignored\n"); */ }
 return EAS_SUCCESS;
 }
 if ((result = Parse_rgn(pDLSData, chunkPos + 12, size, artIndex)) != EAS_SUCCESS)
 return result;
            regionCount++;
 }
 }

 /* set a flag in the last region */
 if ((pDLSData->pDLS != NULL) && (regionCount > 0))
        pDLSData->pDLS->pDLSRegions[pDLSData->regionCount - 1].wtRegion.region.keyGroupAndFlags |= REGION_FLAG_LAST_REGION;

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_ptbl (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 wtblPos, EAS_I32 wtblSize)
{
    EAS_RESULT result;
    EAS_U32 temp;
    EAS_FILE_HANDLE tempFile;
    EAS_U16 waveIndex;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* get the structure size */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &temp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get the number of waves */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSData->waveCount, EAS_FALSE)) != EAS_SUCCESS)
 return result;

#if 0
 /* just need the wave count on the first pass */
 if (!pDLSData->pDLS)
 return EAS_SUCCESS;
#endif

 /* open duplicate file handle */
 if ((result = EAS_HWDupHandle(pDLSData->hwInstData, pDLSData->fileHandle, &tempFile)) != EAS_SUCCESS)
 return result;

 /* read to end of chunk */
 for (waveIndex = 0; waveIndex < pDLSData->waveCount; waveIndex++)
 {

 /* get the offset to the wave and make sure it is within the wtbl chunk */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, tempFile, &temp, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if (temp > (EAS_U32) wtblSize)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "Ptbl offset exceeds size of wtbl\n"); */ }
            EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
 return EAS_ERROR_FILE_FORMAT;
 }

 /* parse the wave */
 if ((result = Parse_wave(pDLSData, wtblPos +(EAS_I32)  temp, waveIndex)) != EAS_SUCCESS)
 return result;
 }

 /* close the temporary handle and return */
    EAS_HWCloseFile(pDLSData->hwInstData, tempFile);
 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_rgn (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_I32 size, EAS_U16 artIndex)
{
    EAS_RESULT result;
    EAS_U32 temp;
    EAS_I32 chunkPos;
    EAS_I32 endChunk;
    EAS_I32 rgnhPos;
    EAS_I32 lartPos;
    EAS_I32 lartSize;
    EAS_I32 lar2Pos;
    EAS_I32 lar2Size;
    EAS_I32 wlnkPos;
    EAS_I32 wsmpPos;
    EAS_U32 waveIndex;
    S_DLS_ART_VALUES art;
    S_WSMP_DATA wsmp;
    S_WSMP_DATA *pWsmp;
    EAS_U16 regionIndex;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* no chunks found yet */
    rgnhPos = lartPos = lartSize = lar2Pos = lar2Size = wsmpPos = wlnkPos = 0;
    regionIndex = (EAS_U16) pDLSData->regionCount;

 /* read to end of chunk */
    endChunk = pos + size;
 while (pos < endChunk)
 {
        chunkPos = pos;

 /* get the next chunk type */
 if ((result = NextChunk(pDLSData, &pos, &temp, &size)) != EAS_SUCCESS)
 return result;

 /* parse useful chunks */
 switch (temp)
 {
 case CHUNK_CDL:
 if ((result = Parse_cdl(pDLSData, size, &temp)) != EAS_SUCCESS)
 return result;

 /* if conditional chunk evaluates false, skip this list */
 if (!temp)
 return EAS_SUCCESS;
 break;

 case CHUNK_RGNH:
                rgnhPos = chunkPos + 8;
 break;

 case CHUNK_WLNK:
                wlnkPos = chunkPos + 8;
 break;

 case CHUNK_WSMP:
                wsmpPos = chunkPos + 8;
 break;

 case CHUNK_LART:
                lartPos = chunkPos + 12;
                lartSize = size;
 break;

 case CHUNK_LAR2:
                lar2Pos = chunkPos + 12;
                lar2Size = size;
 break;

 default:
 break;
 }
 }

 /* must have a rgnh chunk to be useful */
 if (!rgnhPos)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no rgnh chunk\n"); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 /* must have a wlnk chunk to be useful */
 if (!wlnkPos)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_ERROR, "DLS rgn chunk has no wlnk chunk\n"); */ }
 return EAS_ERROR_UNRECOGNIZED_FORMAT;
 }

 /* parse wlnk chunk */
 if ((result = Parse_wlnk(pDLSData, wlnkPos, &waveIndex)) != EAS_SUCCESS)
 return result;
    pWsmp = &pDLSData->wsmpData[waveIndex];

 /* if there is any articulation data, parse it */
    EAS_HWMemCpy(&art, &defaultArt, sizeof(S_DLS_ART_VALUES));
 if (lartPos)
 {
 if ((result = Parse_lart(pDLSData, lartPos, lartSize, &art)) != EAS_SUCCESS)
 return result;
 }

 if (lar2Pos)
 {
 if ((result = Parse_lart(pDLSData, lar2Pos, lar2Size, &art)) != EAS_SUCCESS)
 return result;
 }

 /* if second pass, process region header */
 if (pDLSData->pDLS)
 {

 /* if local data was found convert it */
 if (art.values[PARAM_MODIFIED] == EAS_TRUE)
 {
 Convert_art(pDLSData, &art, (EAS_U16) pDLSData->artCount);
            artIndex = (EAS_U16) pDLSData->artCount;
 }

 /* parse region header */
 if ((result = Parse_rgnh(pDLSData, rgnhPos, &pDLSData->pDLS->pDLSRegions[regionIndex & REGION_INDEX_MASK])) != EAS_SUCCESS)
 return result;

 /* parse wsmp chunk, copying parameters from original first */
 if (wsmpPos)
 {
            EAS_HWMemCpy(&wsmp, pWsmp, sizeof(wsmp));
 if ((result = Parse_wsmp(pDLSData, wsmpPos, &wsmp)) != EAS_SUCCESS)
 return result;

            pWsmp = &wsmp;
 }

 Convert_rgn(pDLSData, regionIndex, artIndex, (EAS_U16) waveIndex, pWsmp);
 }

 /* if local articulation, bump count */
 if (art.values[PARAM_MODIFIED])
        pDLSData->artCount++;

 /* increment region count */
    pDLSData->regionCount++;
 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_rgnh (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_DLS_REGION *pRgn)
{
    EAS_RESULT result;
    EAS_U16 lowKey;
    EAS_U16 highKey;
    EAS_U16 lowVel;
    EAS_U16 highVel;
    EAS_U16 optionFlags;
    EAS_U16 keyGroup;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* get the key range */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowKey, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highKey, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* check the range */
 if (lowKey > 127)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low key out of range [%u]\n", lowKey); */ }
        lowKey = 127;
 }
 if (highKey > 127)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High key out of range [%u]\n", lowKey); */ }
        highKey = 127;
 }

 /* get the velocity range */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &lowVel, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &highVel, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* check the range */
 if (lowVel > 127)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: Low velocity out of range [%u]\n", lowVel); */ }
        lowVel = 127;
 }
 if (highVel > 127)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS rgnh: High velocity out of range [%u]\n", highVel); */ }
        highVel = 127;
 }

 /* get the option flags */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &optionFlags, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get the key group */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &keyGroup, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* save the key range and key group */
    pRgn->wtRegion.region.rangeLow = (EAS_U8) lowKey;
    pRgn->wtRegion.region.rangeHigh = (EAS_U8) highKey;

 /*lint -e{734} keyGroup will always be from 0-15 */
    pRgn->wtRegion.region.keyGroupAndFlags = keyGroup << 8;
    pRgn->velLow = (EAS_U8) lowVel;
    pRgn->velHigh = (EAS_U8) highVel;
 if (optionFlags & F_RGN_OPTION_SELFNONEXCLUSIVE)
        pRgn->wtRegion.region.keyGroupAndFlags |= REGION_FLAG_NON_SELF_EXCLUSIVE;

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT Parse_wlnk (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, EAS_U32 *pWaveIndex)
{
    EAS_RESULT result;

 /* we only care about the the index */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + 8)) != EAS_SUCCESS)
 return result;

 /* read the index */
 return EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle,pWaveIndex, EAS_FALSE);
}

Project: Android

static EAS_RESULT Parse_wsmp (SDLS_SYNTHESIZER_DATA *pDLSData, EAS_I32 pos, S_WSMP_DATA *p)
{
    EAS_RESULT result;
    EAS_U16 wtemp;
    EAS_U32 ltemp;
    EAS_U32 cbSize;

 /* seek to start of chunk */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos)) != EAS_SUCCESS)
 return result;

 /* get structure size */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &cbSize, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get unity note */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &wtemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if (wtemp <= 127)
        p->unityNote = (EAS_U8) wtemp;
 else
 {
        p->unityNote = 60;
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Invalid unity note [%u] in DLS wsmp ignored, set to 60\n", wtemp); */ }
 }

 /* get fine tune */
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->fineTune, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get gain */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->gain, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if (p->gain > 0)
 {
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Positive gain [%ld] in DLS wsmp ignored, set to 0dB\n", p->gain); */ }
        p->gain = 0;
 }

 /* option flags */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* sample loops */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* if looped sample, get loop data */
 if (ltemp)
 {

 if (ltemp > 1)
 { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "DLS sample with %lu loops, ignoring extra loops\n", ltemp); */ }

 /* skip ahead to loop data */
 if ((result = EAS_HWFileSeek(pDLSData->hwInstData, pDLSData->fileHandle, pos + (EAS_I32) cbSize)) != EAS_SUCCESS)
 return result;

 /* get structure size */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get loop type */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &ltemp, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get loop start */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopStart, EAS_FALSE)) != EAS_SUCCESS)
 return result;

 /* get loop length */
 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &p->loopLength, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 }

 return EAS_SUCCESS;
}

Project: Android

static EAS_RESULT PopcdlStack (EAS_U32 *pStack, EAS_INT *pStackPtr, EAS_U32 *pValue)
{

 /* stack underflow, cdl block has an errorr */
 if (*pStackPtr < 0)
 return EAS_ERROR_FILE_FORMAT;

 /* pop the value off the stack */
 *pValue = pStack[*pStackPtr];
 *pStackPtr = *pStackPtr - 1;
 return EAS_SUCCESS;
}

Project: Android

EAS_INLINE void *PtrOfs (void *p, EAS_I32 offset)
{
 return (void*) (((EAS_U8*) p) + offset);
}

Project: Android

static EAS_BOOL QueryGUID (const DLSID *pGUID, EAS_U32 *pValue)
{

 /* assume false */
 *pValue = 0;
 if (EAS_HWMemCmp(&DLSID_GMInHardware, pGUID, sizeof(DLSID)) == 0)
 {
 *pValue = 0xffffffff;
 return EAS_TRUE;
 }

 if (EAS_HWMemCmp(&DLSID_GSInHardware, pGUID, sizeof(DLSID)) == 0)
 return EAS_TRUE;

 if (EAS_HWMemCmp(&DLSID_XGInHardware, pGUID, sizeof(DLSID)) == 0)
 return EAS_TRUE;

 if (EAS_HWMemCmp(&DLSID_SupportsDLS1, pGUID, sizeof(DLSID)) == 0)
 {
 *pValue = 0xffffffff;
 return EAS_TRUE;
 }

 if (EAS_HWMemCmp(&DLSID_SupportsDLS2, pGUID, sizeof(DLSID)) == 0)
 return EAS_TRUE;

 if (EAS_HWMemCmp(&DLSID_SampleMemorySize, pGUID, sizeof(DLSID)) == 0)
 {
 *pValue = MAX_DLS_MEMORY;
 return EAS_TRUE;
 }

 if (EAS_HWMemCmp(&DLSID_ManufacturersID, pGUID, sizeof(DLSID)) == 0)
 {
 *pValue = 0x0000013A;
 return EAS_TRUE;
 }

 if (EAS_HWMemCmp(&DLSID_ProductID, pGUID, sizeof(DLSID)) == 0)
 {
 *pValue = LIB_VERSION;
 return EAS_TRUE;
 }

 if (EAS_HWMemCmp(&DLSID_SamplePlaybackRate, pGUID, sizeof(DLSID)) == 0)
 {
 *pValue = (EAS_U32) outputSampleRate;
 return EAS_TRUE;
 }

 /* unrecognized DLSID */
 return EAS_FALSE;
}

Project: Android

static EAS_RESULT ReadDLSID (SDLS_SYNTHESIZER_DATA *pDLSData, DLSID *pDLSID)
{
    EAS_RESULT result;
    EAS_I32 n;

 if ((result = EAS_HWGetDWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data1, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data2, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 if ((result = EAS_HWGetWord(pDLSData->hwInstData, pDLSData->fileHandle, &pDLSID->Data3, EAS_FALSE)) != EAS_SUCCESS)
 return result;
 return EAS_HWReadFile(pDLSData->hwInstData, pDLSData->fileHandle, pDLSID->Data4, sizeof(pDLSID->Data4), &n);
}