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