mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioUtility.cpp
/*
* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description: This class provides utility functions such as parsing of header
* information for VBR type clips.
*
*/
// INCLUDES
#include "AdvancedAudioUtility.h"
#include "AdvancedAudioDecoder.h"
#include "DebugMacros.h"
#include <mmffile.h>
#include <mmfcontrollerframeworkbase.h>
#include <stdlib.h> // for abs
#include <mmfclip.h>
// CONSTANTS
const TUint64 KMaxScanDuration = 36000000000U; // 10 hours
const TUint KSizeOfTagOffset = 6;
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::CAdvancedAudioUtility
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
EXPORT_C CAdvancedAudioUtility::CAdvancedAudioUtility()
: iPosArr(NULL),
iSamplingRate(0),
iBitRate(0),
iChannels(0),
iSamplesPerFrame(0),
iScanDuration(0),
iScanByteCount(0),
iScanInvByteCount(0),
iSavedLength(0),
iClipSize(0),
iHeaderOffset(0),
iSyncOffset(0),
iNumFrames(0),
iSumBitRate(0),
iLenMetaData(0)
{
iObserver = NULL;
iFrameTimeMs = 0;
iReferenceBitRate = 0;
iScannedOnce = EFalse;
iDecoder = NULL;
}
// Destructor
EXPORT_C CAdvancedAudioUtility::~CAdvancedAudioUtility()
{
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::ScanFramesL
// Scan source buffer, frame by frame to update the frame count, byte count and
// duration. Record controller still uses this, but not play controller.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::ScanFramesL(
CMMFClip* aClip,
CMMFDataBuffer* aBuf,
TBool aScanThisBufferOnly,
TInt /*aSourcePosition*/)
{
if (iScanDuration && !aScanThisBufferOnly)
{
// Already scanned once!
return aBuf->Data().Size();
}
iClipSize = aClip->Size();
if (!aScanThisBufferOnly)
{
iHeaderOffset = this->SeekSync(aBuf, aBuf->Data().Size());
}
TInt readLen;
TInt seekLen;
const TUint8* seekPtr;
TBool Done = EFalse;
TInt SeekOffset = this->SeekSync(aBuf, aBuf->Data().Size());
if (SeekOffset == aBuf->Data().Size())
return SeekOffset;
while (!Done)
{
readLen = aBuf->Data().Length();
seekLen = readLen - SeekOffset;
seekPtr = aBuf->Data().Ptr() + SeekOffset;
TAudioFrameInfo frameInfo;
while (seekLen >= this->FrameHeaderSize())
{
// Scan frame by frame until free format frame or EOB detected.
TInt length = this->FrameInfo(seekPtr, seekLen, frameInfo);
if (length > 0 && frameInfo.iBitRate > 0)
{
// record time position every time the frame length changes
RecordTimeStampL(length);
// update counters
iScanByteCount += length;
iScanDuration += (1000000*frameInfo.iFrameSamples) /
frameInfo.iSamplingRateOut;
iSamplingRate = frameInfo.iSamplingRate;
// Ignoring NO_DATA and SID Frames in bitrate calculation
if (frameInfo.iBitRate != 400 && frameInfo.iBitRate != 2400)
{
iSumBitRate += frameInfo.iBitRate;
iNumFrames++;
iBitRate = iSumBitRate/iNumFrames;
}
iSamplesPerFrame = frameInfo.iFrameSamples;
iChannels = frameInfo.iChannels;
seekPtr += length;
seekLen -= length;
}
else if (frameInfo.iBitRate < 0)
{
seekLen = readLen = 0;
}
else
{
iScanInvByteCount++;
seekPtr++;
seekLen--;
iSavedLength = 0;
}
}
// request more data, if eof or max scan duration has not been exceeded
if ((readLen < this->FrameHeaderSize()) || (iScanDuration > KMaxScanDuration) || aScanThisBufferOnly)
{
Done = ETrue;
}
else
{
// request more data
SeekOffset = 0;
aClip->ReadBufferL(aBuf, iHeaderOffset+iScanByteCount+iScanInvByteCount);
}
}
return aBuf->Data().Size();
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::ScanHeaderL
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::ScanHeaderL(
CMMFDataBuffer* aDataBuf)
{
// currently we are not handling how to search past the metadata
ScanFramesL(aDataBuf, EFalse, 0);
// reset iScanDuration because we didn't scan through the whole file,
// and iScanDuration would not be the Total Duration of the source
iScanDuration = 0;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::ScanFramesL
// Scan source buffer, frame by frame to update the frame count, byte count and
// duration.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::ScanFramesL(
CMMFDataBuffer* aBuf,
TBool aScanThisBufferOnly,
TInt /*aSourcePosition*/)
{
if (!aScanThisBufferOnly)
{
// Already scanned once!
if (iScannedOnce)
return aBuf->Data().Size();
iHeaderOffset = this->SeekSync(aBuf, aBuf->Data().Size());
}
TInt readLen;
TInt seekLen;
const TUint8* seekPtr;
TBool Done = EFalse;
TInt SeekOffset = this->SeekSync(aBuf, aBuf->Data().Size());
while (!Done)
{
readLen = aBuf->Data().Length();
seekLen = readLen - SeekOffset;
seekPtr = aBuf->Data().Ptr() + SeekOffset;
TAudioFrameInfo frameInfo;
while (seekLen >= this->FrameHeaderSize())
{
// Scan frame by frame until free format frame or EOB detected.
TInt length = this->FrameInfo(seekPtr, seekLen, frameInfo);
if (length > 0 && frameInfo.iBitRate > 0)
{
// record time position every time the frame length changes
RecordTimeStampL(length);
// update counters
iScanByteCount += length;
iScanDuration += (1000000*frameInfo.iFrameSamples)/frameInfo.iSamplingRateOut;
iSamplingRate = frameInfo.iSamplingRate;
if (iScanDuration)
iScannedOnce = ETrue;
// Ignoring NO_DATA and SID Frames in bitrate calculation
// this logic here is kinda dangerous, because ScanFramesL can be called
// multiple time when SetPositionL is supported in Streaming/PDL, hence
// the avg bitrate can be mess up the the repeat of the same frame
if (frameInfo.iBitRate != 400 && frameInfo.iBitRate != 2400)
{
iSumBitRate += frameInfo.iBitRate;
iNumFrames++;
iBitRate = iSumBitRate/iNumFrames;
}
iSamplesPerFrame = frameInfo.iFrameSamples;
iChannels = frameInfo.iChannels;
seekPtr += length;
seekLen -= length;
}
else if (frameInfo.iBitRate < 0)
{
seekLen = readLen = 0;
}
else
{
iScanInvByteCount++;
seekPtr++;
seekLen--;
iSavedLength = 0;
}
}
// request more data how? , if eof or max scan duration has not been exceeded
if (aScanThisBufferOnly)
{
Done = ETrue;
}
}
return aBuf->Data().Size();
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::FindFramePos
// Finds the byte position of the frame at given time position.
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::FindFramePos(
const TInt64& aTimePos,
CMMFClip* /*aClip*/)
{
TInt ret = KErrNotFound;
// calculate frame duration
TInt64 frmTime((iSamplesPerFrame*1000000) / iSamplingRate);
// find the closest larger time stamp corresponding to time position
TInt pos = 0;
TTimePos timeStamp((aTimePos), 0, 0);
TKeyArrayFix timeKey(_FOFF(TTimePos,iTimePos),ECmpTInt64);
iPosArr->FindIsq(timeStamp, timeKey, pos);
// calculate byte position based on the closest smaller time stamp
if (iPosArr->Count() > 0)
{
// get the closest smaller
if (pos > 0)
{
pos--;
}
TTimePos& ts = iPosArr->At(pos);
// offset from the closest smaller time stamp
TInt64 dTime = aTimePos - ts.iTimePos;
// time stamp position plus byte offset within this segment
ret = ts.iBytePos + ((dTime / frmTime) * ts.iFrameLen);
}
// limit check
if (ret < 0)
{
ret = 0;
}
if ((ret > iClipSize) && (iClipSize != 0))
{
ret = iClipSize;
}
DP3(_L("CAdvancedAudioUtility::FindFramePos high[%d], low[%d], ret[%d]"), I64HIGH(aTimePos), I64LOW(aTimePos), ret);
return ret;
}
// CAdvancedAudioUtility::FrameInfo
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::FrameInfo(
const TUint8* /*aBuf*/,
TInt /*aBufLen*/,
TAudioFrameInfo& /*aInfo*/)
{
return 0;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SampleRate
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::SampleRate()
{
return iSamplingRate;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::Channels
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::Channels()
{
return iChannels;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::ChannelsOut
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::ChannelsOut()
{
return iChannelsOut;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::ScanDuration
// -----------------------------------------------------------------------------
// get rid of this
EXPORT_C TInt64 CAdvancedAudioUtility::ScanDuration()
{
return iScanDuration;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::Duration
// -----------------------------------------------------------------------------
// default impl
EXPORT_C TInt64 CAdvancedAudioUtility::Duration()
{
DP0(_L("CAdvancedAudioUtility::Duration()"));
TInt64 bitRate = BitRate(); // update bitrate
TInt64 size = iClipSize;
size -= (iSyncOffset+iHeaderOffset);
if (size >= 0)
{
if (bitRate > 0)
{
iDurationUs = size*8000000/bitRate;
}
}
DP3(_L("CAdvancedAudioUtility::Duration() iDuration(ms)[%d] bitRate[%d] size[%d]"), iDurationUs/1000, bitRate, iClipSize-iSyncOffset-iHeaderOffset);
return iDurationUs;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::BitRate
// -----------------------------------------------------------------------------
// default impl - BitRate() would be called by user and updates reference
EXPORT_C TInt CAdvancedAudioUtility::BitRate()
{
if (iDecoder && !iBitRateFrozen)
{
TInt bitrate = iDecoder->BitRate();
if (bitrate > 0)
{
iBitRate = bitrate;
}
}
return iBitRate;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::HeaderOffset
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::HeaderOffset()
{
return iHeaderOffset;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SyncOffset
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::SyncOffset()
{
return iSyncOffset;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SetCodecConfigData
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::SetCodecConfigData(
RArray<TInt>& /*aCodecConfig*/)
{
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SetObserver
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::SetObserver(MAdvancedAudioUtilityObserver& aObserver)
{
iObserver = &aObserver;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SetDecoder
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::SetDecoder(CAdvancedAudioDecoder& aDecoder)
{
iDecoder = &aDecoder;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::DeReferenceDecoder
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::DeReferenceDecoder()
{
iDecoder = NULL;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::FrameHeaderSize
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::FrameHeaderSize()
{
return 0;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::GetDriveNumber
// -----------------------------------------------------------------------------
// is this needed?
EXPORT_C TDriveNumber CAdvancedAudioUtility::GetDriveNumber(
const TDesC& aDriveName)
{
TDriveNumber driveNumber = EDriveC;
if (!aDriveName.Length())
{
return driveNumber;
}
else
{
switch (aDriveName[0])
{
case 'a':
case 'A':
driveNumber = EDriveA;
break;
case 'b':
case 'B':
driveNumber = EDriveB;
break;
case 'c':
case 'C':
driveNumber = EDriveC;
break;
case 'd':
case 'D':
driveNumber = EDriveD;
break;
case 'e':
case 'E':
driveNumber = EDriveE;
break;
case 'f':
case 'F':
driveNumber = EDriveF;
break;
case 'g':
case 'G':
driveNumber = EDriveG;
break;
case 'h':
case 'H':
driveNumber = EDriveH;
break;
case 'i':
case 'I':
driveNumber = EDriveI;
break;
case 'j':
case 'J':
driveNumber = EDriveJ;
break;
case 'k':
case 'K':
driveNumber = EDriveK;
break;
case 'l':
case 'L':
driveNumber = EDriveL;
break;
case 'm':
case 'M':
driveNumber = EDriveM;
break;
case 'n':
case 'N':
driveNumber = EDriveN;
break;
case 'o':
case 'O':
driveNumber = EDriveO;
break;
case 'p':
case 'P':
driveNumber = EDriveP;
break;
case 'q':
case 'Q':
driveNumber = EDriveQ;
break;
case 'r':
case 'R':
driveNumber = EDriveR;
break;
case 's':
case 'S':
driveNumber = EDriveS;
break;
case 't':
case 'T':
driveNumber = EDriveT;
break;
case 'u':
case 'U':
driveNumber = EDriveU;
break;
case 'v':
case 'V':
driveNumber = EDriveV;
break;
case 'x':
case 'X':
driveNumber = EDriveX;
break;
case 'y':
case 'Y':
driveNumber = EDriveY;
break;
case 'z':
case 'Z':
driveNumber = EDriveZ;
break;
default:
break;
}
}
return driveNumber;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SetClipSizeL
// Set/Update the iClipSize varilable
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::SetClipSizeL(TUint aSize)
{
DP1(_L("CAdvancedAudioUtility::SetClipSizeL size[%d]"), aSize);
if (aSize > (iSyncOffset+iHeaderOffset))
{
iClipSize = aSize;
}
else
{
User::Leave(KErrArgument);
}
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::EnableBitRateChangedEventL
// Enable bitrate change callback
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::EnableBitRateChangedEventL(TInt aIntervalInMilliSeconds)
{
if (!iObserver)
User::Leave(KErrNotReady);
else if (aIntervalInMilliSeconds < -1)
User::Leave(KErrArgument);
if (iDecoder)
{
TInt err = KErrNone;
if (aIntervalInMilliSeconds == -1)
err = iDecoder->EnableDecodeIntervalEvent(EFalse);
else
err = iDecoder->EnableDecodeIntervalEvent(ETrue, aIntervalInMilliSeconds);
// KErrNone means the decoder would callback on desire interval as it decodes
// KErrNotSupported implys Utility would need to keep track of the interval
// otherwise, leave on any other situation
if (err == KErrNone)
return;
else if (err != KErrNotSupported)
User::LeaveIfError(err);
}
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SetSourceReference
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::SetSourceReference(TUint aTimeMs, TUint aPos)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->SetSourceReference(aTimeMs, aPos);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::FindFramePosFromTime
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::FindFramePosFromTime(TUint& aTimeMs, TUint& aPos)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->FindFramePosFromTime(aTimeMs, aPos);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
EXPORT_C TInt CAdvancedAudioUtility::FindFrameTimeFromPos(TUint& aTime, TUint& aPos)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->FindFrameTimeFromPos(aTime, aPos);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::LastFramePos
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::LastFramePos(TUint& aPos)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->LastFramePos(aPos);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::LastFrameTime
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::LastFrameTime(TUint& aTimeMs)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->LastFrameTime(aTimeMs);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::ResetTable
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::ResetTable()
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->ResetTable();
}
else
{
stat = KErrNotSupported;
}
return stat;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::SeekToTimeMs
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::SeekToTimeMs(TUint aTimeMs)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->SeekToTimeMs(aTimeMs);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
EXPORT_C TInt CAdvancedAudioUtility::SetPlayWindowEndTimeMs(TUint aTimeMs)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->SetPlayWindowEndTimeMs(aTimeMs);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::RecordTimeStampL
// Record time position every time the frame length changes or when the stamp
// array is empty. Positioning is accurate up to KMaxScanDuration. After that
// the last time stamp is used for estimating the position..
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::RecordTimeStampL(
TInt aFrameLength)
{
// record time position every time the frame length
// changes or empty stamp array
TInt pos = iScanInvByteCount + iScanByteCount;
TInt count = iPosArr->Count();
TTimePos lastEntry(0,0,0);
if (count > 0)
lastEntry = (*iPosArr)[iPosArr->Count()-1];
DP5(_L("CAdvancedAudioUtility::RecordTimeStampL Count[%d], iScanDuration[%d]millsec, BytePos[%d], aFrameLength[%d], lastEntry.iTimePos[%d]millsec"), count, I64LOW(iScanDuration/1000), pos, aFrameLength, I64LOW(lastEntry.iTimePos/1000));
if (((pos > lastEntry.iBytePos) && aFrameLength != 0 && aFrameLength != iSavedLength) || (count == 0))
{
if (iScanDuration <= KMaxScanDuration)
{
DP0(_L("CAdvancedAudioUtility::RecordTimeStampL, AppendL new entry"));
TTimePos timeStamp(I64LOW(iScanDuration), pos, aFrameLength);
iPosArr->AppendL(timeStamp);
iSavedLength = aFrameLength;
}
}
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::MetaDataLength
// -----------------------------------------------------------------------------
//
EXPORT_C TInt CAdvancedAudioUtility::ID3HeaderLength(
const CMMFDataBuffer* aBuf)
{
TInt lenMetaData;
TUint offset = aBuf->Position();
_LIT8 (KTagID3, "ID3");
TPtrC8 searchBuf;
// Set search buffer
searchBuf.Set(aBuf->Data());
const TUint8* ptr = aBuf->Data().Ptr();
TInt len = aBuf->Data().Length();
searchBuf.Set(ptr+offset, len-offset);
TInt startTagPos = searchBuf.Find (KTagID3);
if (startTagPos == KErrNotFound || startTagPos != 0)
{
lenMetaData = 0;
}
else
{
lenMetaData = searchBuf[KSizeOfTagOffset];
lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+1] << 1)) >> 1;
lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+2] << 1)) >> 1;
lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+3] << 1)) >> 1;
lenMetaData += 10;
}
return lenMetaData;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::CreateBufferOfSizeLC
// -----------------------------------------------------------------------------
//
EXPORT_C CMMFDataBuffer* CAdvancedAudioUtility::CreateBufferOfSizeLC(
TUint aSize)
{
CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(aSize);
CleanupStack::PushL(buffer);
buffer->Data().FillZ(aSize);
buffer->SetRequestSizeL(aSize);
buffer->Data().SetLength(0);
return buffer;
}
// -----------------------------------------------------------------------------
// CAdvancedAudioUtility::DecodeIntervalEvent
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::DecodeIntervalEvent()
{
if (iObserver)
{
BitRate(); // updates iBitRate
TInt lim = iReferenceBitRate/10; // 10% tolerance
if (abs(iReferenceBitRate - iBitRate) > lim)
{
iObserver->BitRateChanged();
iReferenceBitRate = iBitRate;
}
}
}
/*
EXPORT_C TInt CAdvancedAudioUtility::IsSeeking(TBool& aIsSeeking)
{
TInt stat;
if (iDecoder)
{
stat = iDecoder->IsSeeking(aIsSeeking);
}
else
{
stat = KErrNotSupported;
}
return stat;
}
*/
// -----------------------------------------------------------------------------
// CAdvancedAudioDecoder::SeekPositionReached
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::SeekPositionReached(TUint aTimeMs)
{
iObserver->SeekPositionReached(aTimeMs);
}
// -----------------------------------------------------------------------------
// CAdvancedAudioDecoder::PlayWindowEndPositionReached
// -----------------------------------------------------------------------------
//
EXPORT_C void CAdvancedAudioUtility::PlayWindowEndPositionReached()
{
iObserver->PlayWindowEndPositionReached();
}
EXPORT_C TInt CAdvancedAudioUtility::GetOffsets(TInt& aOffsets)
{
aOffsets = iHeaderOffset + iSyncOffset;
return KErrNone;
}
// End of File