omxil/mmilapi/unittest/test_plugins/dummypcmrenderer/dummypcmrenderer.cpp
changeset 0 40261b775718
child 16 eedf2dcd43c6
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "dummypcmrenderer.h"
       
    17 #include "iltestuids.hrh"
       
    18 #include "tilstructtypes.h"
       
    19 #include <ecom/implementationproxy.h>
       
    20 #include <mmf/server/mmfdatabuffer.h>
       
    21 
       
    22 
       
    23 #define KDummyPCM16FormatUid 0x10111126 //dummy
       
    24 
       
    25 const TInt KBufferSize = 16384;			// we need 16k to hold a pcm packet
       
    26 
       
    27 const TInt KDefaultSampleRate = 8000;
       
    28 const TInt KDefaultNumberChannels = 1;
       
    29 
       
    30 const TInt KInputPortIndex = 0;
       
    31 	
       
    32 
       
    33 // ------------------------------------------------------------------------------------------
       
    34 // CDummyPcmRenderer::CInputPort Implementation
       
    35 	
       
    36 CDummyPcmRenderer::CInputPort::CInputPort(CDummyPcmRenderer& aParent) 
       
    37 	: CActive(EPriorityNormal),
       
    38 	  iParent(aParent),
       
    39 	  iSampleRate(KDefaultSampleRate),
       
    40 	  iChannels(KDefaultNumberChannels),
       
    41 	  iBufferSize(KBufferSize)
       
    42 	{
       
    43 	CActiveScheduler::Add(this);	
       
    44 	}
       
    45 		
       
    46 CDummyPcmRenderer::CInputPort::~CInputPort()
       
    47 	{
       
    48 	Cancel();
       
    49 	iBuffers.Close();
       
    50 	}
       
    51 
       
    52 CDummyPcmRenderer::CInputPort* CDummyPcmRenderer::CInputPort::NewL(CDummyPcmRenderer& aParent)
       
    53 	{
       
    54 	CInputPort* self = new (ELeave) CInputPort(aParent);
       
    55 	return self;
       
    56 	}
       
    57 
       
    58 TInt CDummyPcmRenderer::CInputPort::FillThisBuffer(CMMFBuffer& /*aInputBuffer*/)
       
    59 	{
       
    60 	return KErrNotSupported;
       
    61 	}
       
    62 
       
    63 TInt CDummyPcmRenderer::CInputPort::EmptyThisBuffer(const CMMFBuffer& aInputBuffer)
       
    64 	{
       
    65 	TInt err = iBuffers.Append(&aInputBuffer);
       
    66 	if (err == KErrNone)
       
    67 		{
       
    68 		TILComponentState state;
       
    69 		if (iParent.GetState(state) != KErrNone)
       
    70 			{
       
    71 			return EComponentInvalid;		
       
    72 			}
       
    73 		if (state == EComponentExecuting && !IsActive())
       
    74 			{
       
    75 			SetActive();
       
    76 			TRequestStatus* status = &iStatus;
       
    77 			User::RequestComplete(status, KErrNone);
       
    78 			}
       
    79 		}
       
    80 	return err;
       
    81 	}
       
    82 	
       
    83 TInt CDummyPcmRenderer::CInputPort::TunnelRequest(MILComponentPortIf* aPort)
       
    84 	{
       
    85 	TILComponentState state;
       
    86 	if (iParent.GetState(state) != KErrNone)
       
    87 		{
       
    88 		return EComponentInvalid;		
       
    89 		}
       
    90 	if (( state != EComponentLoaded) && (!iStopped))
       
    91 		{
       
    92 		return EComponentInvalid;
       
    93 		}
       
    94 	
       
    95 	if (iPortConnectedTo)
       
    96 		{
       
    97 		// the port is already connected, return an error
       
    98 		return EPortAlreadyTunnelled;
       
    99 		}
       
   100 	iPortConnectedTo = const_cast<MILComponentPortIf*>(aPort);
       
   101 	return KErrNone;
       
   102 	}
       
   103 	
       
   104 TInt CDummyPcmRenderer::CInputPort::DisconnectTunnel(MILComponentPortIf* /*aPort*/)
       
   105 	{
       
   106 	return KErrNotSupported;
       
   107 	}
       
   108 
       
   109 TInt CDummyPcmRenderer::CInputPort::PortIndex() const
       
   110 	{
       
   111 	return KInputPortIndex;
       
   112 	}	
       
   113 	
       
   114 TPortDirection CDummyPcmRenderer::CInputPort::PortDirection() const
       
   115 	{
       
   116 	return EDirInput;
       
   117 	}
       
   118 
       
   119 	
       
   120 CMMFBuffer* CDummyPcmRenderer::CInputPort::CreateBufferL(TInt /*aBufferSize*/)
       
   121 	{
       
   122 	User::Leave(KErrNotSupported);
       
   123 	return NULL;
       
   124 	}
       
   125 	
       
   126 TInt CDummyPcmRenderer::CInputPort::UseBuffer(CMMFBuffer& /*aBuffer*/)
       
   127 	{
       
   128 	return KErrNotSupported;
       
   129 	}
       
   130 
       
   131 TInt CDummyPcmRenderer::CInputPort::FreeBuffer(CMMFBuffer* /*aBuffer*/)
       
   132 	{
       
   133 	return KErrNotSupported;
       
   134 	}
       
   135 
       
   136 TInt CDummyPcmRenderer::CInputPort::FlushPort()
       
   137 	{
       
   138 	return KErrNotSupported;
       
   139 	}
       
   140 
       
   141 TInt CDummyPcmRenderer::CInputPort::EnablePort()
       
   142 	{
       
   143 	return KErrNotSupported;
       
   144 	}
       
   145 
       
   146 TInt CDummyPcmRenderer::CInputPort::DisablePort()
       
   147 	{
       
   148 	return KErrNotSupported;
       
   149 	}
       
   150 
       
   151 MILComponentIf* CDummyPcmRenderer::CInputPort::PortComponent() const
       
   152 	{
       
   153 	return &iParent;
       
   154 	}
       
   155 
       
   156 void CDummyPcmRenderer::CInputPort::SetVolume(TUint aVolume)
       
   157 	{
       
   158 	iVolume = aVolume;
       
   159 	}
       
   160 
       
   161 TUint CDummyPcmRenderer::CInputPort::Volume()
       
   162 	{
       
   163 	return iVolume;
       
   164 	}
       
   165 
       
   166 TUint CDummyPcmRenderer::CInputPort::BytesPlayed()
       
   167 	{
       
   168 	return iBytesPlayed;
       
   169 	}
       
   170 
       
   171 void CDummyPcmRenderer::CInputPort::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
       
   172 	{
       
   173 	iRampDuration = aRampDuration;
       
   174 	}
       
   175 
       
   176 TTimeIntervalMicroSeconds& CDummyPcmRenderer::CInputPort::VolumeRamp()
       
   177 	{
       
   178 	return iRampDuration;
       
   179 	}
       
   180 
       
   181 TInt CDummyPcmRenderer::CInputPort::SampleRate()
       
   182 	{
       
   183 	return iSampleRate;
       
   184 	}
       
   185 	
       
   186 TInt CDummyPcmRenderer::CInputPort::Channels()
       
   187 	{
       
   188 	return iChannels;
       
   189 	}	
       
   190 	
       
   191 TUint32 CDummyPcmRenderer::CInputPort::BufferSize() const
       
   192 	{
       
   193 	return iBufferSize;
       
   194 	}
       
   195 
       
   196 void CDummyPcmRenderer::CInputPort::Execute()
       
   197 	{
       
   198 	if (!IsActive() && iBuffers.Count()>0)
       
   199 		{
       
   200 		SetActive();
       
   201 		TRequestStatus* status = &iStatus;
       
   202 		User::RequestComplete(status, KErrNone);
       
   203 		}
       
   204 	}
       
   205 
       
   206 void CDummyPcmRenderer::CInputPort::Pause()
       
   207 	{
       
   208 	if (iParent.SoundDevice().Handle())
       
   209 		{
       
   210 		iParent.SoundDevice().PausePlayBuffer();
       
   211 		}
       
   212 	}
       
   213 	
       
   214 void CDummyPcmRenderer::CInputPort::Stop()
       
   215 	{
       
   216 	Cancel();	
       
   217 	}
       
   218 
       
   219 void CDummyPcmRenderer::CInputPort::RunL()
       
   220 	{
       
   221 
       
   222 	if (iCurrentBuffer != NULL)
       
   223 		{
       
   224 		// If we've been signalled with a buffer, callback that we've completed the writing of the
       
   225 		// buffer
       
   226 		if (iParent.Observer())
       
   227 			{		
       
   228 			iParent.Observer()->BufferDelivered(this, iCurrentBuffer);
       
   229 			if (iCurrentBuffer->LastBuffer())
       
   230 				{
       
   231 				TILEvent thisEvent;
       
   232 				thisEvent.iEvent = EEventBufferFlag;
       
   233 				thisEvent.iData1 = PortIndex();				
       
   234 				thisEvent.iData2 = static_cast<TUint32>(KErrUnderflow); 
       
   235 				iParent.Observer()->MsgFromILComponent(&iParent, thisEvent); 
       
   236 				iParent.SoundDevice().Close();
       
   237 				}
       
   238 			}
       
   239 		iCurrentBuffer = NULL;
       
   240 		}
       
   241 		
       
   242 	// only process the next buffer if there is no error
       
   243 	// error callbacks were handled in the previous block
       
   244 	if (iStatus == KErrNone)
       
   245 		{
       
   246 		if (iBuffers.Count()>0)
       
   247 			{
       
   248 			iCurrentBuffer = iBuffers[0];
       
   249 			iBuffers.Remove(0);
       
   250 			
       
   251 			if (CMMFBuffer::IsSupportedDataBuffer(iCurrentBuffer->Type()))
       
   252 				{
       
   253  				TDes8& aBufferDes = (static_cast<CMMFDataBuffer*>(iCurrentBuffer))->Data();
       
   254  				iStatus = KRequestPending;
       
   255 				iParent.SoundDevice().PlayData(iStatus, aBufferDes);
       
   256 				SetActive();
       
   257 				}
       
   258 			}
       
   259 		}
       
   260 	else
       
   261 		{
       
   262 		// In the real implementation here should be sending an error event back to the client
       
   263 		}
       
   264 	}
       
   265 
       
   266 void CDummyPcmRenderer::CInputPort::DoCancel()
       
   267 	{
       
   268 	if (iParent.SoundDevice().Handle())
       
   269 		{
       
   270 		iParent.SoundDevice().CancelPlayData();
       
   271 		iParent.SoundDevice().FlushPlayBuffer();
       
   272 		}
       
   273 	}
       
   274 
       
   275 // ------------------------------------------------------------------------------------------
       
   276 // CDummyPcmRenderer Implementation
       
   277 	
       
   278 CDummyPcmRenderer::CDummyPcmRenderer()
       
   279 	{
       
   280 	}
       
   281 	
       
   282 CDummyPcmRenderer::~CDummyPcmRenderer()
       
   283 	{
       
   284 	delete iInputPort;
       
   285 	iSoundDevice.Close();
       
   286 	}
       
   287 	
       
   288 CDummyPcmRenderer* CDummyPcmRenderer::NewL()
       
   289 	{
       
   290 	CDummyPcmRenderer* self = new (ELeave) CDummyPcmRenderer;
       
   291 	return self;
       
   292 	}
       
   293 	
       
   294 void CDummyPcmRenderer::CreateComponentL(const TDesC8& /*aComponentName*/, MILIfObserver& aComponentIfObserver)
       
   295 	{
       
   296 	iObserver = &aComponentIfObserver;
       
   297 	iInputPort = CInputPort::NewL(*this);
       
   298 	iState = EComponentLoaded;
       
   299 	}
       
   300 
       
   301 void CDummyPcmRenderer::CreateComponentL(const TUid& /*aUid*/, MILIfObserver& /*aComponentIfObserver*/)	
       
   302 	{
       
   303 	User::LeaveIfError(KErrNotSupported);
       
   304 	};
       
   305 
       
   306 void CDummyPcmRenderer::ReleaseComponent()
       
   307 	{
       
   308 	delete this;	
       
   309 	}
       
   310 
       
   311 TInt CDummyPcmRenderer::GetComponentInputPorts(RPointerArray<MILComponentPortIf>& aComponentPorts) const
       
   312 	{
       
   313 	return aComponentPorts.Append(iInputPort);
       
   314 	}
       
   315 
       
   316 TInt CDummyPcmRenderer::GetComponentOutputPorts(RPointerArray<MILComponentPortIf>& /*aComponentPorts*/) const
       
   317 	{
       
   318 	return KErrNotSupported;
       
   319 	}
       
   320 
       
   321 TInt CDummyPcmRenderer::SetConfig(const TILStruct& aConfig, const MILComponentPortIf* /*aComponentPort*/)
       
   322 	{
       
   323 	if (aConfig.Uid() == TUid::Uid(KUidMMFTTaskConfig))
       
   324 		{
       
   325 		const TTaskConfig* config = TILTaskConfig::GetStructure(aConfig);	
       
   326 		ASSERT(config);
       
   327 		iInputPort->iSampleRate = config->iRate;
       
   328 		iInputPort->iChannels = (config->iStereoMode & ETaskMono)? 1 : 2;
       
   329 		iInputPort->iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse;
       
   330 		return KErrNone;
       
   331 		}
       
   332 	
       
   333 	return KErrNotSupported;
       
   334 	}
       
   335 
       
   336 TInt CDummyPcmRenderer::GetConfig(TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) const
       
   337 	{
       
   338 	return KErrNotSupported;
       
   339 	}
       
   340 
       
   341 TInt CDummyPcmRenderer::Initialize()
       
   342 	{
       
   343 	ASSERT(iObserver);
       
   344 	
       
   345 	TILEvent thisEvent;
       
   346 	thisEvent.iEvent = EEventCmdComplete;
       
   347 	thisEvent.iData1 = ECommandStateSet;				
       
   348 	thisEvent.iData2 = EComponentIdle;
       
   349 	iObserver->MsgFromILComponent(this, thisEvent); 
       
   350 
       
   351 	iState = EComponentIdle;
       
   352 	return KErrNone;	
       
   353 	}
       
   354 	
       
   355 TInt CDummyPcmRenderer::UnInitialize()
       
   356 	{
       
   357 	ASSERT(iObserver);
       
   358 	
       
   359 	TILEvent thisEvent;
       
   360 	thisEvent.iEvent = EEventCmdComplete;
       
   361 	thisEvent.iData1 = ECommandStateSet;				
       
   362 	thisEvent.iData2 = EComponentLoaded;
       
   363 	iObserver->MsgFromILComponent(this, thisEvent); 
       
   364 
       
   365 	iState = EComponentLoaded;
       
   366 	return KErrNone;	
       
   367 	}
       
   368 
       
   369 TInt CDummyPcmRenderer::Execute()
       
   370 	{
       
   371 	ASSERT(iObserver);
       
   372 	TInt err = KErrNone;
       
   373 	if(!iSoundDevice.Handle())
       
   374 		{
       
   375 		err = iSoundDevice.Open();
       
   376 		}
       
   377 	
       
   378 	RMdaDevSound::TCurrentSoundFormatBuf buf;
       
   379 	if (err == KErrNone)
       
   380 		{
       
   381 		if(iState == EComponentPaused)
       
   382 			{
       
   383 			iSoundDevice.ResumePlaying();
       
   384 			}
       
   385 		else
       
   386 			{
       
   387 			// Set play format (for input port)
       
   388 			iSoundDevice.GetPlayFormat(buf);
       
   389 			buf().iRate = iInputPort->SampleRate();
       
   390 			buf().iChannels = iInputPort->Channels();
       
   391 			buf().iBufferSize = KBufferSize;
       
   392 			buf().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
       
   393 			err = iSoundDevice.SetPlayFormat(buf);
       
   394 			}
       
   395 		}
       
   396 	iState = EComponentExecuting;	
       
   397 
       
   398 	TILEvent thisEvent;
       
   399 	thisEvent.iEvent = EEventCmdComplete;
       
   400 	thisEvent.iData1 = ECommandStateSet;				
       
   401 	thisEvent.iData2 = EComponentExecuting;
       
   402 	iObserver->MsgFromILComponent(this, thisEvent); 
       
   403 
       
   404 	return err;		
       
   405 	}
       
   406 
       
   407 TInt CDummyPcmRenderer::Pause()
       
   408 	{
       
   409 	iState = EComponentPaused;
       
   410 	iInputPort->Pause();
       
   411 	return KErrNone;
       
   412 	}
       
   413 
       
   414 TInt CDummyPcmRenderer::Stop()
       
   415 	{
       
   416 	if(iState == EComponentExecuting || iState == EComponentPaused)
       
   417 		{
       
   418 		// Cancel and flush the device driver		
       
   419 		iInputPort->Stop();
       
   420 
       
   421 		TILEvent thisEvent;
       
   422 		thisEvent.iEvent = EEventCmdComplete;
       
   423 		thisEvent.iData1 = ECommandStateSet;				
       
   424 		thisEvent.iData2 = EComponentIdle;
       
   425 		iObserver->MsgFromILComponent(this, thisEvent); 
       
   426 
       
   427 		iState = EComponentIdle;
       
   428 		
       
   429 		// Close the sound device
       
   430 		iSoundDevice.Close();
       
   431 			
       
   432 		return KErrNone;			
       
   433 		}	
       
   434 	else
       
   435 		{
       
   436 		// invalid state
       
   437 		return EComponentInvalid;			
       
   438 		}	
       
   439 	}
       
   440 
       
   441 TInt CDummyPcmRenderer::GetState(TILComponentState& aState) const
       
   442 	{
       
   443 	aState = iState;
       
   444 	return KErrNone;	
       
   445 	}
       
   446 			
       
   447 TInt CDummyPcmRenderer::SendCommand(const TILCommand& /*aCommand*/)
       
   448 	{
       
   449 	return KErrNotSupported;
       
   450 	}
       
   451 
       
   452 TInt CDummyPcmRenderer::FlushAllPorts()
       
   453 	{
       
   454 	return KErrNotSupported;
       
   455 	}
       
   456 
       
   457 TInt CDummyPcmRenderer::ComponentRoleEnum(TPtr8& /*aComponentRole*/, TUint32 /*aIndex*/) const
       
   458 	{
       
   459 	return KErrNotSupported;
       
   460 	}
       
   461 
       
   462 TInt CDummyPcmRenderer::GetComponentVersion(TILComponentVersion& /*aVersion*/) const
       
   463 	{
       
   464 	return KErrNotSupported;
       
   465 	}
       
   466 
       
   467 TInt CDummyPcmRenderer::SetComponentIfRole(const TDesC8& /*aComponentRole*/)
       
   468 	{
       
   469 	return KErrNotSupported;
       
   470 	}
       
   471 
       
   472 TInt CDummyPcmRenderer::GetComponentIfRole(TDes8& /*aComponentRole*/) const
       
   473 	{
       
   474 	return KErrNotSupported;
       
   475 	}
       
   476 
       
   477 TInt CDummyPcmRenderer::SetComponentIfRole(const TUid& /*aFormat*/)
       
   478 	{
       
   479 	// This interface is specific writen to support only this PCM renderer role
       
   480 	return KErrNotSupported;
       
   481 	}
       
   482 
       
   483 TInt CDummyPcmRenderer::GetComponentIfRole(TUid& aFormat) const
       
   484 	{
       
   485 	aFormat = TUid::Uid(KDummyPCM16FormatUid);
       
   486 	return KErrNone;	
       
   487 	}
       
   488 	
       
   489 TAny* CDummyPcmRenderer::CustomInterface(TUid aUid)
       
   490 	{
       
   491 	if (aUid.iUid == KMmfPlaySettingsCustomInterface)
       
   492 		{
       
   493 		return static_cast<MPlayCustomInterface*>(iInputPort);
       
   494 		}
       
   495 	return NULL;	
       
   496 	}	
       
   497 
       
   498 TInt CDummyPcmRenderer::SetExtConfig(const TDesC8& /*aParameterName*/, const TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/)
       
   499 	{
       
   500 	return KErrNotSupported;		
       
   501 	}
       
   502 
       
   503 TInt CDummyPcmRenderer::GetExtConfig(const TDesC8& /*aParameterName*/, TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) const
       
   504 	{
       
   505 	return KErrNotSupported;		
       
   506 	}
       
   507 
       
   508 
       
   509 MILIfObserver* CDummyPcmRenderer::Observer() const
       
   510 	{
       
   511 	return iObserver;	
       
   512 	}
       
   513 		
       
   514 RMdaDevSound& CDummyPcmRenderer::SoundDevice()
       
   515 	{
       
   516 	return iSoundDevice;
       
   517 	}
       
   518 	
       
   519 
       
   520 // ------------------------------------------------------------------------------------------	
       
   521 // ECOM Implementation table entry	
       
   522 	
       
   523 const TImplementationProxy ImplementationTable[] = 
       
   524 	{
       
   525 	IMPLEMENTATION_PROXY_ENTRY(KUidDummyPcmRendererMILIFPlugin,	CDummyPcmRenderer::NewL),
       
   526 	};
       
   527 
       
   528 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
   529 	{
       
   530 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   531 	return ImplementationTable;
       
   532 	}