📄 oggpluginadaptor.cpp
字号:
/*
* Copyright (c) 2004 OggPlay Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// Platform settings
#include <OggOs.h>
// This file is for PLUGIN_SYSTEM only
#if defined(PLUGIN_SYSTEM)
#include <e32base.h>
#include "OggAbsPlayback.h"
#include "OggPluginAdaptor.h"
#include <e32svr.h>
#include <badesca.h>
#include "OggLog.h"
#include "f32file.h"
#ifdef MMF_AVAILABLE
#include "ImplementationUIDs.hrh"
#include "OggPlayControllerCustomCommands.h"
#endif /* MMF_AVAILABLE */
// CPluginInfo
CPluginInfo::CPluginInfo()
{
}
CPluginInfo* CPluginInfo::NewL(const TDesC& anExtension,
const CMMFFormatImplementationInformation &aFormatInfo,
const TUid aControllerUid)
{
CPluginInfo* self = new (ELeave) CPluginInfo();
CleanupStack::PushL(self);
self->ConstructL(anExtension, aFormatInfo,aControllerUid);
CleanupStack::Pop(); // self
return self;
}
void
CPluginInfo::ConstructL(const TDesC& anExtension,
const CMMFFormatImplementationInformation &aFormatInfo,
const TUid aControllerUid)
{
iExtension = anExtension.AllocL();
iFormatUid = aFormatInfo.Uid();
iName = aFormatInfo.DisplayName().AllocL();
iSupplier = aFormatInfo.Supplier().AllocL();
iVersion = aFormatInfo.Version();
iControllerUid = aControllerUid;
}
CPluginInfo::~CPluginInfo()
{
if ( iExtension) delete iExtension;
if ( iName ) delete iName;
if ( iSupplier ) delete iSupplier;
}
////////////////////////////////////////////////////////////////
//
// CPluginSupportedList
//
////////////////////////////////////////////////////////////////
CPluginSupportedList::CPluginSupportedList()
{}
void CPluginSupportedList::ConstructL()
{
iPlugins = new(ELeave) CArrayPtrFlat <TExtensionList>(3);
}
CPluginSupportedList::~CPluginSupportedList()
{
for (TInt i=0; i<iPlugins->Count();i++)
{
iPlugins->At(i)->listPluginInfos->ResetAndDestroy();
delete(iPlugins->At(i)->listPluginInfos);
}
iPlugins->ResetAndDestroy();
delete(iPlugins);
}
void CPluginSupportedList::AddPluginL(
const TDesC &anExtension,
const CMMFFormatImplementationInformation &aFormatInfo,
const TUid aControllerUid)
{
CPluginInfo* info = CPluginInfo::NewL(anExtension, aFormatInfo, aControllerUid);
CleanupStack::PushL(info);
AddExtension(anExtension);
TInt index = FindListL(anExtension);
// Add the plugin to the existing list
TExtensionList * list = iPlugins->At(index);
list->listPluginInfos->AppendL(info);
CleanupStack::Pop(info);
}
void CPluginSupportedList::SelectPluginL(const TDesC& anExtension, TUid aSelectedUid)
{
TInt index = FindListL(anExtension);
if(index <0)
User::Leave(KErrNotFound);
TExtensionList * list = iPlugins->At(index);
if (aSelectedUid == TUid::Null())
{
list->selectedPlugin = NULL;
return;
}
TBool found = EFalse;
for(TInt i =0; i<list->listPluginInfos->Count(); i++)
{
if (list->listPluginInfos->At(i)->iControllerUid == aSelectedUid)
{
list->selectedPlugin = list->listPluginInfos->At (i) ;
found = ETrue;
}
}
if ( !found ) User::Leave(KErrNotFound);
}
CDesCArrayFlat * CPluginSupportedList::SupportedExtensions()
{
CDesCArrayFlat * extensions = NULL;
TRAPD(err,
{
extensions = new (ELeave) CDesCArrayFlat (3);
CleanupStack::PushL(extensions);
for (TInt i=0; i<iPlugins->Count(); i++)
{
extensions->AppendL(iPlugins->At(i)->extension);
}
CleanupStack::Pop();
}
) // END OF TRAP
return(extensions);
}
TInt CPluginSupportedList::FindListL(const TDesC &anExtension)
{
for (TInt i=0; i<iPlugins->Count(); i++)
{
if ( anExtension.CompareF( iPlugins->At(i)->extension ) == 0)
{
return(i);
}
}
return(-1); // Not found
}
CPluginInfo * CPluginSupportedList::GetSelectedPluginInfo(const TDesC &anExtension)
{
TInt index = FindListL(anExtension);
if(index <0)
return NULL;
TExtensionList * list = iPlugins->At(index);
if (list == NULL)
return NULL;
return (list->selectedPlugin);
}
CArrayPtrFlat <CPluginInfo> * CPluginSupportedList::GetPluginInfoList(const TDesC &anExtension)
{
TInt index = FindListL(anExtension);
if(index <0)
return NULL;
TExtensionList * list = iPlugins->At(index);
if (list == NULL)
return NULL;
return (list->listPluginInfos);
}
void CPluginSupportedList::AddExtension(const TDesC &anExtension)
{
TInt index = FindListL(anExtension);
if(index >=0)
return; // The extension already exists
// List not found, create a new list
TExtensionList * list = new (ELeave) TExtensionList;
CleanupStack::PushL(list);
list->listPluginInfos = new (ELeave) CArrayPtrFlat <CPluginInfo>(1);
list->extension = anExtension;
list->selectedPlugin = NULL;
iPlugins->AppendL(list);
CleanupStack::Pop(list);
}
////////////////////////////////////////////////////////////////
//
// COggPluginAdaptor
//
////////////////////////////////////////////////////////////////
COggPluginAdaptor::COggPluginAdaptor(COggMsgEnv* anEnv, MPlaybackObserver* anObserver = 0)
:CAbsPlayback(anObserver), iEnv(anEnv), iVolume(KMaxVolume), iGain(ENoGain)
{
}
TInt COggPluginAdaptor::Info(const TDesC& aFileName, TBool /*silent*/)
{
// That's unfortunate, but we must open the file first before the info
// can be retrieved. This adds some serious delay when discovering the files
return Open(aFileName);
}
void COggPluginAdaptor::OpenL(const TDesC& aFileName)
{
if (aFileName != iFileName)
{
TRACEF(COggLog::VA(_L("OpenL %S"), &aFileName ));
iTitle = KNullDesC;
iAlbum = KNullDesC;
iArtist = KNullDesC;
iGenre = KNullDesC;
iTrackNumber = KNullDesC;
ConstructAPlayerL(aFileName);
// Find the selected plugin, corresponding to file type
TParsePtrC p( aFileName);
TPtrC pp (p.Ext().Mid(1));
CPluginInfo * info = GetPluginListL().GetSelectedPluginInfo(pp);
if (info == NULL)
User::Leave(KErrNotFound);
iPluginControllerUID = info->iControllerUid;
iPlayer->OpenFileL(aFileName, KNullUid, iPluginControllerUID);
// Wait for the init completed callback
iError = KErrNone;
#ifdef MMF_AVAILABLE
if (!iWait.IsStarted())
{
iWait.Start();
}
#endif
User::LeaveIfError(iError);
iState = EStreamOpen;
iFileName = aFileName;
TInt nbMetaData;
CMMFMetaDataEntry * aMetaData;
TInt err = iPlayer->GetNumberOfMetaDataEntries(nbMetaData);
if (err != KErrNone)
nbMetaData = 0;
HBufC *metadataValue = HBufC::NewLC(128);
TPtr metadataValueDes(metadataValue->Des());
for (TInt i=0; i< nbMetaData; i++)
{
aMetaData = iPlayer->GetMetaDataEntryL(i);
ParseMetaDataValueL(*aMetaData, metadataValueDes);
const TDesC& name(aMetaData->Name());
const TDesC& value(aMetaData->Value());
TRACEF(COggLog::VA(_L("MetaData %S : %S"), &name, &value ));
if ( name == _L("title") )
iTitle = *metadataValue;
if ( name == _L("album") )
iAlbum = *metadataValue;
if ( name == _L("artist") )
iArtist = *metadataValue;
if ( name == _L("genre") )
iGenre = *metadataValue;
if ( name == _L("albumtrack") )
iTrackNumber = *metadataValue;
// If it is not an OggPlay Plugin, there should be some handling here to guess
// title, trackname, ...
delete aMetaData;
}
CleanupStack::PopAndDestroy(metadataValue);
// Get additional audio properties (using a custom command)
GetAudioProperties();
// Clear the frequency analyser
Mem::FillZ(&iFreqBins, sizeof(iFreqBins));
iState = EStopped;
SetVolume(iVolume);
}
// Set the volume gain
SetVolumeGain(iGain);
}
void COggPluginAdaptor::ParseMetaDataValueL(CMMFMetaDataEntry &aMetaData, TDes &aDestinationBuffer )
{
// Try to remove all TABs, CR and LF
// having those around is screwing up the SW
HBufC * tempBuf = aMetaData.Value().AllocL();
CleanupStack::PushL(tempBuf);
tempBuf->Des().Zero();
TLex parse(aMetaData.Value() );
TBool first=ETrue;
for ( ; ; )
{
TPtrC16 token = parse.NextToken();
if (token.Length() <=0 )
break;
if (!first)
tempBuf->Des().Append(_L(" "));
tempBuf->Des().Append(token);
first = EFalse;
}
// Crop to the final buffer
aDestinationBuffer = tempBuf->Left(aDestinationBuffer.MaxLength());
CleanupStack::PopAndDestroy(tempBuf);
TRACEF(COggLog::VA(_L("COggPluginAdaptor::ParseMetaDataValueL !%S!"),&aDestinationBuffer));
}
TInt COggPluginAdaptor::Open(const TDesC& aFileName)
{
TRAPD(leaveCode, OpenL(aFileName));
return (leaveCode);
}
void COggPluginAdaptor::Pause()
{
TRACEF(_L("COggPluginAdaptor::Pause()"));
if (!iInterrupted)
iLastPosition = iPlayer->Position();
iPlayer->Stop();
iState = EPaused;
}
void COggPluginAdaptor::Resume()
{
TRACEF(_L("COggPluginAdaptor::Resume()"));
iPlayer->SetPosition(iLastPosition);
Play();
#if defined (SERIES60V3)
TInt time = TInt(I64INT(iLastPosition.Int64()) / 1000000);
#else
TInt time = TInt(iLastPosition.Int64().GetTInt() / 1000000);
#endif
TInt hours = time/3600;
TInt min = (time%3600)/60;
TInt sec = (time%3600%60);
TRACEF(COggLog::VA(_L(" %i %i %i"),hours,min,sec));
}
void COggPluginAdaptor::Play()
{
TRACEF(_L("COggPluginAdaptor::Play() In"));
iInterrupted = EFalse;
if ((iState == EClosed) || (iState == EStreamOpen))
return; // Cannot play if we haven't opened a file
TRAPD(err, iPlayer->PlayL());
if (err) return; // Silently ignore the problem :-(
iState = EPlaying;
iObserver->ResumeUpdates();
TRACEF(_L("COggPluginAdaptor::Play() Out"));
}
void COggPluginAdaptor::Stop()
{
TRACEF(_L("COggPluginAdaptor::Stop()"));
iPlayer->Stop();
iState = EStopped;
// The Stop is synchroneous within the MMF Framework.
ClearComments();
iObserver->NotifyUpdate();
}
void COggPluginAdaptor::SetVolume(TInt aVol)
{
TRACEF(_L("COggPluginAdaptor::SetVolume()"));
if ( (aVol <0) || (aVol >KMaxVolume) )
return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -