156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * File:
456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * eas_imaadpcm.c
556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Contents and purpose:
756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Implements the IMA ADPCM decoder
856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Copyright Sonic Network Inc. 2005
107df30109963092559d3760c0661a020f9daf1030The Android Open Source Project
117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * you may not use this file except in compliance with the License.
137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * You may obtain a copy of the License at
147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * See the License for the specific language governing permissions and
217df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * limitations under the License.
2256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Revision Control:
2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Revision: 847 $
2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Date: 2007-08-27 21:30:08 -0700 (Mon, 27 Aug 2007) $
2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_data.h"
3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_host.h"
3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_pcm.h"
3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_math.h"
3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_report.h"
3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks// #define _DEBUG_IMA_ADPCM_LOCATE
3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * externs
4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern const EAS_I16 imaIndexTable[];
4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksextern const EAS_I16 imaStepSizeTable[];
4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * prototypes
4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState);
5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble);
5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time);
5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * IMA ADPCM Decoder interface
5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksconst S_DECODER_INTERFACE IMADecoder =
5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    IMADecoderInit,
6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    IMADecoderSample,
6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    IMADecoderLocate
6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks};
6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * IMADecoderInit()
6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Initializes the IMA ADPCM decoder
7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*lint -esym(715, pEASData) common decoder interface - pEASData not used */
8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT IMADecoderInit (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pState->decoderL.step = 0;
8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pState->decoderR.step = 0;
8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * IMADecoderSample()
9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Decodes an IMA ADPCM sample
9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT IMADecoderSample (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState)
10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_RESULT result;
10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I16 sTemp;
10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* if high nibble, decode */
11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pState->hiNibble)
11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte >> 4));
11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pState->hiNibble = EAS_FALSE;
11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* low nibble, need to fetch another byte */
11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* check for loop */
12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if ((pState->bytesLeft == 0) && (pState->loopSamples != 0))
12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* seek to start of loop */
12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if ((result = EAS_HWFileSeek(pEASData->hwInstData, pState->fileHandle, (EAS_I32) (pState->startPos + pState->loopLocation))) != EAS_SUCCESS)
12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                return result;
12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pState->bytesLeft = pState->byteCount = (EAS_I32) pState->bytesLeftLoop;
12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pState->blockCount = 0;
12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pState->flags &= ~PCM_FLAGS_EMPTY;
12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "IMADecoderSample: Rewind file to %d, bytesLeft = %d\n", pState->startPos, pState->bytesLeft); */ }
13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* if start of block, fetch new predictor and step index */
13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if ((pState->blockSize != 0) && (pState->blockCount == 0) && (pState->bytesLeft != 0))
13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* get predicted sample for left channel */
13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                return result;
13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM
14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Predictor: Was %d, now %d\n", pState->decoderL.acc, sTemp); */ }
14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pState->decoderL.acc = pState->decoderL.x1 = sTemp;
14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* get step index for left channel - upper 8 bits are reserved */
14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                return result;
14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM
14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderL.step, sTemp); */ }
14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pState->decoderL.step = sTemp & 0xff;
15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (pState->flags & PCM_FLAGS_STEREO)
15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* get predicted sample for right channel */
15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    return result;
15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->decoderR.acc = pState->decoderR.x1 = sTemp;
15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* get step index for right channel - upper 8 bits are reserved */
16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if ((result = EAS_HWGetWord(pEASData->hwInstData, pState->fileHandle, &sTemp, EAS_FALSE)) != EAS_SUCCESS)
16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    return result;
16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM
16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Step: Was %d, now %d\n", pState->decoderR.step, sTemp); */ }
16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->decoderR.step = sTemp & 0xff;
16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->blockCount = pState->blockSize - 8;
16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->bytesLeft -= 8;
16956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
17056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
17156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
17256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->blockCount = pState->blockSize - 4;
17356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->bytesLeft -= 4;
17456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
17556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
17656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        else
17756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
17856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
17956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* get another ADPCM data pair */
18056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (pState->bytesLeft)
18156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
18256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if ((result = EAS_HWGetByte(pEASData->hwInstData, pState->fileHandle, &pState->srcByte)) != EAS_SUCCESS)
18456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    return result;
18556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* decode the low nibble */
18756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->bytesLeft--;
18856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->blockCount--;
18956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                IMADecoderADPCM(&pState->decoderL, (EAS_U8)(pState->srcByte & 0x0f));
19056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
19156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (pState->flags & PCM_FLAGS_STEREO)
19256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    IMADecoderADPCM(&pState->decoderR, (EAS_U8)(pState->srcByte >> 4));
19356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                else
19456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    pState->hiNibble = EAS_TRUE;
19556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
19656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
19756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* out of ADPCM data, generate enough samples to fill buffer */
19856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
19956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
20056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->decoderL.x1 = pState->decoderL.x0;
20156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pState->decoderR.x1 = pState->decoderR.x0;
20256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
20356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
20456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
20556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
20756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
20856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
21056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * IMADecoderADPCM()
21156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
21256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
21356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Decodes an IMA ADPCM sample
21456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
21556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
21656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
21756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
21856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
21956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
22256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
22456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
22556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic void IMADecoderADPCM (S_DECODER_STATE *pState, EAS_U8 nibble)
22656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
22756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_INT delta;
22856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_INT stepSize;
22956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
23056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* get stepsize from table */
23156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    stepSize = imaStepSizeTable[pState->step];
23256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
23356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* delta = (abs(delta) + 0.5) * step / 4 */
23456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    delta = 0;
23556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (nibble & 4)
23656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        delta += stepSize;
23756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
23856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (nibble & 2)
23956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{702} use shift for performance */
24056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        delta += stepSize >> 1;
24156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
24256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (nibble & 1)
24356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /*lint -e{702} use shift for performance */
24456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        delta += stepSize >> 2;
24556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
24656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /*lint -e{702} use shift for performance */
24756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    delta += stepSize >> 3;
24856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
24956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* integrate the delta */
25056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (nibble & 8)
25156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      pState->acc -= delta;
25256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
25356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks      pState->acc += delta;
25456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
25556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* saturate */
25656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pState->acc > 32767)
25756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pState->acc = 32767;
25856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pState->acc < -32768)
25956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pState->acc = -32768;
26056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pState->x1 = (EAS_PCM) pState->acc;
26156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* compute new step size */
26356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pState->step += imaIndexTable[nibble];
26456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pState->step < 0)
26556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pState->step = 0;
26656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pState->step > 88)
26756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pState->step = 88;
26856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM
27056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "In=%u, Pred=%d, Step=%d\n", nibble, pState->acc,  imaStepSizeTable[pState->step]); */ }
27156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
27256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
27356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
27456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
27556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * IMADecoderLocate()
27656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
27756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Locate in an IMA ADPCM stream
27856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
27956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
28056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT IMADecoderLocate (EAS_DATA_HANDLE pEASData, S_PCM_STATE *pState, EAS_I32 time)
28156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
28256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_RESULT result;
28356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 temp;
28456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 samplesPerBlock;
28556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_I32 secs, msecs;
28656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
28756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* no need to calculate if time is zero */
28856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (time == 0)
28956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp = 0;
29056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* not zero */
29256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
29356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
29456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* can't seek if not a blocked file */
29656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pState->blockSize == 0)
29756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return EAS_ERROR_FEATURE_NOT_AVAILABLE;
29856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* calculate number of samples per block */
30056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pState->flags & PCM_FLAGS_STEREO)
30156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samplesPerBlock = pState->blockSize - 7;
30256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        else
30356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samplesPerBlock = (pState->blockSize << 1) - 7;
30456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
30556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* break down into secs and msecs */
30656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        secs = time / 1000;
30756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        msecs = time - (secs * 1000);
30856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
30956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* calculate sample number fraction from msecs */
31056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp = (msecs * pState->sampleRate);
31156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp = (temp >> 10) + ((temp * 49) >> 21);
31256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* add integer sample count */
31456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp += secs * pState->sampleRate;
31556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM_LOCATE
31756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000006 , time, temp);
31856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
31956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
32056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* for looped samples, calculate position in the loop */
32156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if ((temp > pState->byteCount) && (pState->loopSamples != 0))
32256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
32356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            EAS_I32 numBlocks;
32456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            EAS_I32 samplesPerLoop;
32556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            EAS_I32 samplesInLastBlock;
32656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
32756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            numBlocks = (EAS_I32) (pState->loopStart / pState->blockSize);
32856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samplesInLastBlock = (EAS_I32) pState->loopStart - (numBlocks * pState->blockSize);
32956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (samplesInLastBlock)
33056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
33156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (pState->flags & PCM_FLAGS_STEREO)
33256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    samplesInLastBlock = samplesInLastBlock - 7;
33356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                else
33456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    /*lint -e{703} use shift for performance */
33556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    samplesInLastBlock = (samplesInLastBlock << 1) - 7;
33656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
33756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            samplesPerLoop = numBlocks * samplesPerBlock + samplesInLastBlock;
33856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            temp = temp % samplesPerLoop;
33956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM_LOCATE
34056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000007 , numBlocks, samplesPerLoop, samplesInLastBlock, temp);
34156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
34256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
34356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* find start of block for requested sample */
34556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        temp = (temp / samplesPerBlock) * pState->blockSize;
34656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM_LOCATE
34756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000008 , temp);
34856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
34956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
35056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
35156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
35256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* seek to new location */
35356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if ((result = EAS_PESeek(pEASData, pState, &temp)) != EAS_SUCCESS)
35456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return result;
35556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
35656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef _DEBUG_IMA_ADPCM_LOCATE
35756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_ReportEx(_EAS_SEVERITY_NOFILTER, 0x2380b977, 0x00000009 , pState->bytesLeft);
35856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
35956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* reset state */
36156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pState->blockCount = 0;
36256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pState->hiNibble = EAS_FALSE;
36356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if ((pState->state != EAS_STATE_PAUSING) && (pState->state != EAS_STATE_PAUSED))
36456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pState->state = EAS_STATE_READY;
36556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
36756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
36856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
369