//#include "log.h"
#include "AacPlayerEngine.h"
//#include "BrokenCallObject.h"
//#include "AudioController.h"
CAacPlayerEngine::CAacPlayerEngine(MAudioPlayerEngineObserver& aObserver) :
iObserver(aObserver)
{
iPlayState = ENUM_PLAY_STOP;
}
CAacPlayerEngine::~CAacPlayerEngine()
{
if (iPlayerStream)
{
iPlayerStream->Stop();
}
ClearData();
delete iCodec;
delete iPlayerStream;
}
void CAacPlayerEngine::ClearData()
{
iAacData.ResetAndDestroy();
iWavData.ResetAndDestroy();
delete iAacRemainData;
iAacRemainData = NULL;
delete iCurrWavData;
iCurrWavData = NULL;
iPlayedBytes = 0;
iTotalBytes = 0;
}
CAacPlayerEngine* CAacPlayerEngine::NewL(MAudioPlayerEngineObserver& aObserver)
{
CAacPlayerEngine* self = NewLC(aObserver);
CleanupStack::Pop(self);
return self;
}
CAacPlayerEngine* CAacPlayerEngine::NewLC(MAudioPlayerEngineObserver& aObserver)
{
CAacPlayerEngine* self = new (ELeave) CAacPlayerEngine(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CAacPlayerEngine::ConstructL()
{
//LOG(_L("enter CAacPlayerEngine::ConstructL"));
RArray<TInt> configParams;
configParams.Append(0);//16000);
configParams.Append(0);//1);
configParams.Append(0);//1);
configParams.Append(0);//1024);
configParams.Append(0);
configParams.Append(0);
configParams.Append(0);
configParams.Append(0);
configParams.Append(16);
configParams.Append(0);
iCodec = CMMFCodec::NewL(TUid::Uid(0x101faf81));
iCodec->ConfigureL(TUid::Uid(KUidMmfCodecAudioSettings),
(TDesC8&) configParams);
configParams.Close();
iPlayerStream = CMdaAudioOutputStream::NewL(*this);
iPlayerStream->Open(&iStreamSettings);
//LOG(_L("leave CAacPlayerEngine::ConstructL"));
}
void CAacPlayerEngine::PlayL()
{
ClearData();
iPlayState = ENUM_PLAY_PLAY;
}
void CAacPlayerEngine::Stop()
{
//首先停止
iPlayerStream->Stop();
//清除资源
ClearData();
//记标记位
iPlayState = ENUM_PLAY_STOP;
//重至
iWaitingData = ETrue;
}
void CAacPlayerEngine::PauseL()
{
//记标记位
iPlayState = ENUM_PLAY_PAUSE;
}
void CAacPlayerEngine::ResumeL()
{
//继续Copy数据
WriteStreamData();
//记标记位
iPlayState = ENUM_PLAY_PLAY;
}
//功能描述:设置播放器的音量百分比
//参数描述:无
//返回值 :无
void CAacPlayerEngine::SetVolume(TInt aPercent)
{
TInt aMaxVolume = iPlayerStream->MaxVolume();
iPlayerStream->SetVolume(aMaxVolume * aPercent / 100);
}
void CAacPlayerEngine::MaoscOpenComplete(TInt aError)
{
//LOG_FORMAT((_L("enter CAacPlayerEngine::MaoscOpenComplete = %d"), aError));
if (aError == KErrNone)
{
iInit = ETrue;
iPlayerStream->SetDataTypeL(KMMFFourCCCodePCM16);
// iPlayerStream->SetAudioPropertiesL(
// TMdaAudioDataSettings::ESampleRate16000Hz,
// TMdaAudioDataSettings::EChannelsStereo);
iPlayerStream->SetAudioPropertiesL(
TMdaAudioDataSettings::ESampleRate22050Hz,
TMdaAudioDataSettings::EChannelsMono);
TInt aMaxVolume = iPlayerStream->MaxVolume();
iPlayerStream->SetVolume(aMaxVolume * 50 / 100);
iPlayerStream->SetPriority(EPriorityNormal, EMdaPriorityPreferenceNone);
WriteStreamData();
}
else
{
Stop();
}
TRAPD(err, iObserver.AudioOpenCompleteNotifyL(aError));
//LOG(_L("leave CAacPlayerEngine::MaoscOpenComplete"));
}
void CAacPlayerEngine::MaoscBufferCopied(TInt aError, const TDesC8& /*aBuffer*/)
{
////LOG(_L("enter CAacPlayerEngine::MaoscBufferCopied"));
delete iCurrWavData;
iCurrWavData = NULL;
if (aError == KErrNone)
{
if (iPlayState != ENUM_PLAY_PAUSE)
{
WriteStreamData();
}
}
else
{
TRAPD(err, iObserver.AudioErrorNotifyL(aError));
}
////LOG(_L("leave CAacPlayerEngine::MaoscBufferCopied"));
}
void CAacPlayerEngine::MaoscPlayComplete(TInt aError)
{
//LOG_FORMAT((_L("enter CAacPlayerEngine::MaoscPlayComplete = %d"), aError));
delete iCurrWavData;
iCurrWavData = NULL;
if (aError == KErrUnderflow || aError == KErrNone)
{
if (iPlayState != ENUM_PLAY_PAUSE)
{
//LOG_FORMAT((_L("iPlayedBytes = %d, iTotalBytes = %d"), iPlayedBytes, iTotalBytes));
if (iTotalBytes - iPlayedBytes > iTotalBytes / 20)
{
WriteStreamData();
}
else
{
TRAPD(err, iObserver.AudioPlayCompleteNotifyL(KErrNone));
}
}
}
else
{
TRAPD(err, iObserver.AudioPlayCompleteNotifyL(aError));
}
//LOG(_L("leave CAacPlayerEngine::MaoscPlayComplete"));
}
TInt CAacPlayerEngine::AppendData(const TDesC8& aData)
{
////LOG(_L("enter CAacPlayerEngine::AppendData"));
const TInt SEGMENT_SIZE = 1024;
const TInt SEGMENT_LIMIT_SIZE = 300;
TInt len = aData.Length();
TInt pos = 0;
while (pos < len)
{
TInt size = SEGMENT_SIZE;
if (len - pos - size < SEGMENT_LIMIT_SIZE)
{
size = len - pos;
}
HBufC8* data = HBufC8::NewL(size);
data->Des().Copy(aData.Mid(pos, size));
iAacData.AppendL(data);
pos += size;
}
//LOG_FORMAT((_L("CAacPlayerEngine::AppendData iInit = %d, iWaitingData = %d"), iInit, iWaitingData));
if (iPlayState != ENUM_PLAY_PAUSE && iWaitingData && iInit)
{
WriteStreamData();
}
////LOG(_L("leave CAacPlayerEngine::AppendData"));
return iAacData.Count();
}
void CAacPlayerEngine::WriteStreamData()
{
////LOG(_L("enter CAacPlayerEngine::WriteStreamData"));
//检测AAC的Buf数
this->ResposeBufCount();
//当前数据还在播放, 所以只能忽略
if (iCurrWavData)
{
return;
}
if (iWavData.Count() < 1)
{
PoliticDecode();
}
DoWriteStreamData();
////LOG(_L("leave CAacPlayerEngine::WriteStreamData"));
}
void CAacPlayerEngine::PoliticDecode()
{
////LOG(_L("enter CAacPlayerEngine::PoliticDecode"));
if (iWavData.Count() < 1)
{
TInt num = Min(iAacData.Count(), 1);
for (TInt i = 0; i < num; i++)
{
HBufC8* data = iAacData[0];
iAacData.Remove(0);
CMMFDescriptorBuffer* dest = Aac2Wav(data->Des());
delete data;
if (dest)
{
iWavData.AppendL(dest);
}
else
{
//LOG(_L("Aac2Wav failed, so notify finish"));
// CBrokenCallObject::NewBrokenCallLD(&CallFinishNotifyL, this);
}
}
}
////LOG(_L("leave CAacPlayerEngine::PoliticDecode"));
}
void CAacPlayerEngine::DoWriteStreamData()
{
//LOG_FORMAT((_L("enter CAacPlayerEngine::DoWriteStreamData::MaoscPlayComplete = %d"), iWaitingData));
if (iWavData.Count() > 0)
{
__ASSERT_DEBUG(iCurrWavData == NULL, User::Panic(_L("error iCurrWavData != NULL"), KErrInUse));
iCurrWavData = iWavData[0];
iWavData.Remove(0);
iPlayerStream->WriteL(iCurrWavData->Data());
iWaitingData = EFalse;
}
else
{
iWaitingData = ETrue;
}
//LOG_FORMAT((_L("leave CAacPlayerEngine::DoWriteStreamData::MaoscPlayComplete = %d"), iWaitingData));
}
CMMFDescriptorBuffer* CAacPlayerEngine::Aac2Wav(const TDesC8& aData)
{
////LOG(_L("enter CAacPlayerEngine::Aac2Wav"));
TInt remainLen = 0;
if (iAacRemainData)
{
remainLen = iAacRemainData->Des().Length();
}
CMMFDescriptorBuffer* src = CMMFDescriptorBuffer::NewL(aData.Length()
+ remainLen);
TPtr8 ptr((TUint8*) (src->Data().Ptr()), 0, src->Data().MaxLength());
if (iAacRemainData)
{
ptr.Append(iAacRemainData->Des());
delete iAacRemainData;
iAacRemainData = NULL;
}
ptr.Append(aData);
TInt frameNum = 0;
TInt len = ptr.Length();
TInt lastFramePos = 0;
const TUint8* datap = ptr.Ptr();
TInt i = 0;
while (i < (len - 6))
{
if ((datap[i] != 0xff) || ((datap[i + 1] & 0xf0) != 0xf0))
{
if ((datap[i + 2] & 0xf0) != 0xf0)
{
//LOG_FORMAT((_L("datap[%d] = 0x%02x, datap[%d] = 0x%02x, datap[%d] = 0x%02x"), i, datap[i], i+1, datap[i+1], i+2, datap[i+2]));
}
i++;
continue;
}
lastFramePos = i;
TInt frameSize = (datap[i + 2] << 24) | (datap[i + 3] << 16) | (datap[i
+ 4] << 8) | datap[i + 5];
frameSize &= 0x0003ffc0;
frameSize >>= 5;
if (frameSize + i > len)
{ /