os/mm/mmdevicefw/mdf/src/audio/AudioDevice/audiodevice.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2005-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 <ecom/implementationproxy.h>
    17 #include <mmf/server/mmfdatabuffer.h>
    18 #include "audiodevice.hrh"
    19 #include "audiodevice.h"
    20 #include <e32debug.h>
    21 #include <mdf/mdfpuconfig.h>
    22 #include <mda/common/audio.h>
    23 
    24 // we need 16k to hold a pcm packet
    25 const TInt KBufferSize = 16384;
    26 
    27 const TInt KDefaultSampleRate = 8000;
    28 const TInt KDefaultNumberChannels = 1;
    29 _LIT(KAudioDevicePanic, "CAudioDevice Panic");
    30 
    31 enum TAudioDevicePanics
    32 	{
    33 	EObserverNotSet, 
    34 	EInvalidUsage
    35 	};
    36 	
    37 const TInt KInputPortIndex = 0;
    38 const TInt KOutputPortIndex = 1;
    39 	
    40 // ------------------------------------------------------------------------------------------	
    41 // CAudioDevice::CInput port class implementation
    42 
    43 	
    44 CAudioDevice::CInputPort::CInputPort(CAudioDevice& aParent) 
    45 	: CActive(EPriorityNormal),
    46 	  iParent(aParent),
    47 	  iSampleRate(KDefaultSampleRate),
    48 	  iChannels(KDefaultNumberChannels),
    49 	  iBufferSize(KBufferSize)
    50 	{
    51 	}
    52 		
    53 CAudioDevice::CInputPort::~CInputPort()
    54 	{
    55 	Cancel();
    56 	iBuffers.Close();
    57 	}
    58 
    59 CAudioDevice::CInputPort* CAudioDevice::CInputPort::NewL(CAudioDevice& aParent)
    60 	{
    61 	CInputPort* self = new (ELeave) CInputPort(aParent);
    62 	CleanupStack::PushL(self);
    63 	self->ConstructL();
    64 	CleanupStack::Pop(self);
    65 	return self;
    66 	}
    67 
    68 void CAudioDevice::CInputPort::ConstructL()
    69 	{
    70 	CActiveScheduler::Add(this);	
    71 	}
    72 
    73 TInt CAudioDevice::CInputPort::MipConfigure(const TPuConfig& aConfig)
    74 	{
    75 	if (aConfig.Uid() == TUid::Uid(KUidTTaskConfig))
    76 		{
    77 		const TTaskConfig* config = TPuTaskConfig::GetStructure(aConfig);	
    78 	
    79 		iSampleRate = config->iRate;
    80 		iChannels = (config->iStereoMode & ETaskMono)? 1 : 2;
    81 		iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse;
    82 		return KErrNone;
    83 		}
    84 	
    85 	if (aConfig.Uid() == TUid::Uid(KUidTTaskConfig2))
    86 		{
    87 		const TTaskConfig2* config = TPuTaskConfig2::GetStructure(aConfig);	
    88 	
    89 		iSampleRate = config->iRate;
    90 		iChannels = config->iNumberOfChannels;
    91 		iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse;
    92 		return KErrNone;
    93 		}	
    94 		
    95 	return KErrNotSupported;
    96 	}
    97 
    98 TInt CAudioDevice::CInputPort::MipGetConfig(TPuConfig& /*aConfig*/)
    99 	{
   100 	return KErrNotSupported;
   101 	}
   102 
   103 TInt CAudioDevice::CInputPort::MipTunnelRequest(const MMdfOutputPort& aOutputPortToBeConnectedTo,
   104 			TTunnelFlags& /*aTunnelFlags*/, TSupplierType& /*aSupplierType*/)
   105 	{
   106 	if ((iParent.State()!=EProcessingUnitLoaded) && (!iStopped))
   107 		{
   108 		// invalid state
   109 		return EInvalidState;
   110 		}
   111 	
   112 	if (iPortConnectedTo)
   113 		{
   114 		// the port is already connected, return an error
   115 		return EPortAlreadyTunnelled;
   116 		}
   117 	iPortConnectedTo = const_cast<MMdfOutputPort*>(&aOutputPortToBeConnectedTo);
   118 	return KErrNone;
   119 	}
   120 
   121 void CAudioDevice::CInputPort::MipWriteData(CMMFBuffer& aInputBuffer)
   122 	{
   123 	TInt err = iBuffers.Append(&aInputBuffer);
   124 	if (err == KErrNone)
   125 		{
   126 		if (iParent.State() == EProcessingUnitExecuting && !IsActive())
   127 			{
   128 			SetActive();
   129 			TRequestStatus* status = &iStatus;
   130 			User::RequestComplete(status, KErrNone);
   131 			}
   132 		}
   133 	else
   134 		{
   135 		if (iObserver)
   136 			{
   137 			iObserver->MipoWriteDataComplete(this, &aInputBuffer, err);
   138 			}
   139 		}
   140 	}
   141 
   142 void CAudioDevice::CInputPort::Execute()
   143 	{
   144 	if (!IsActive() && iBuffers.Count()>0)
   145 		{
   146 		SetActive();
   147 		TRequestStatus* status = &iStatus;
   148 		User::RequestComplete(status, KErrNone);
   149 		}
   150 	}
   151 
   152 TBool CAudioDevice::CInputPort::MipIsTunnelled() const
   153 	{
   154 	if (iPortConnectedTo)
   155 		{
   156 		return ETrue;
   157 		}
   158 	else
   159 		{
   160 		return EFalse;			
   161 		}
   162 	}
   163 
   164 TInt CAudioDevice::CInputPort::MipIndex() const
   165 	{
   166 	return KInputPortIndex;
   167 	}
   168 	
   169 CMMFBuffer* CAudioDevice::CInputPort::MipCreateBuffer(TInt /*aBufferSize*/)
   170 	{
   171 	__ASSERT_ALWAYS(EFalse, User::Panic(KAudioDevicePanic, EInvalidUsage));
   172 	return NULL;
   173 	}
   174 
   175 TInt CAudioDevice::CInputPort::MipUseBuffer(CMMFBuffer& /*aBuffer*/)
   176 	{
   177 	return KErrNone;
   178 	}
   179 
   180 TInt CAudioDevice::CInputPort::MipFreeBuffer(CMMFBuffer* /*aBuffer*/)
   181 	{
   182 	return KErrNone;
   183 	}
   184 	
   185 void CAudioDevice::CInputPort::MipDisconnectTunnel()
   186 	{
   187 	}
   188 
   189 void CAudioDevice::CInputPort::MipRestartTunnel()
   190 	{
   191 	}
   192 
   193 TUint32 CAudioDevice::CInputPort::MipBufferSize() const
   194 	{
   195 	return iBufferSize;
   196 	}
   197 
   198 void CAudioDevice::CInputPort::Pause()
   199 	{
   200 	if (iParent.SoundDevice().Handle())
   201 		{
   202 		iParent.SoundDevice().PausePlayBuffer();
   203 		}
   204 	}
   205 	
   206 void CAudioDevice::CInputPort::Stop()
   207 	{
   208 	Cancel();	
   209 	}
   210 	
   211 TInt CAudioDevice::CInputPort::MipCreateCustomInterface(TUid aUid)
   212 	{
   213 	if (aUid.iUid == KMmfPlaySettingsCustomInterface)
   214 		{
   215 		return KErrNone;
   216 		}
   217 	return KErrNotSupported;	
   218 	}
   219 
   220 TAny* CAudioDevice::CInputPort::MipCustomInterface(TUid aUid)
   221 	{
   222 	if (aUid.iUid == KMmfPlaySettingsCustomInterface)
   223 		{
   224 		return static_cast<MPlayCustomInterface*>(this);
   225 		}
   226 	return NULL;
   227 	}
   228 	
   229 void CAudioDevice::CInputPort::SetVolume(TUint aVolume)
   230 	{
   231 	iVolume = aVolume;
   232 	}
   233 
   234 TUint CAudioDevice::CInputPort::Volume()
   235 	{
   236 	return iVolume;
   237 	}
   238 
   239 TUint CAudioDevice::CInputPort::BytesPlayed()
   240 	{
   241 	return iBytesPlayed;
   242 	}
   243 
   244 void CAudioDevice::CInputPort::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
   245 	{
   246 	iRampDuration = aRampDuration;
   247 	}
   248 
   249 TTimeIntervalMicroSeconds& CAudioDevice::CInputPort::VolumeRamp()
   250 	{
   251 	return iRampDuration;
   252 	}
   253 
   254 void CAudioDevice::CInputPort::RunL()
   255 	{
   256 	if (iCurrentBuffer != NULL)
   257 		{
   258 		// If we've been signalled with a buffer, callback that we've completed the writing of the
   259 		// buffer
   260 		if (iObserver)
   261 			{		
   262 			iObserver->MipoWriteDataComplete(this, iCurrentBuffer, iStatus.Int());
   263 			if (iCurrentBuffer->LastBuffer())
   264 				{
   265 				iParent.Observer()->ExecuteComplete(&iParent, KErrUnderflow);
   266 				iParent.SoundDevice().Close();
   267 				}
   268 			}
   269 		iCurrentBuffer = NULL;
   270 		}
   271 	// only process the next buffer if there is no error
   272 	// error callbacks were handled in the previous block
   273 	if (iStatus == KErrNone)
   274 		{
   275 		if (iBuffers.Count()>0)
   276 			{
   277 			iCurrentBuffer = iBuffers[0];
   278 			iBuffers.Remove(0);
   279 			
   280 			if (CMMFBuffer::IsSupportedDataBuffer(iCurrentBuffer->Type()))
   281 				{
   282  				TDes8& aBufferDes = (static_cast<CMMFDataBuffer*>(iCurrentBuffer))->Data();
   283  				iStatus = KRequestPending;
   284 				iParent.SoundDevice().PlayData(iStatus, aBufferDes);
   285 				SetActive();
   286 				}
   287 			}
   288 		}
   289 	}
   290 
   291 void CAudioDevice::CInputPort::DoCancel()
   292 	{
   293 	if (iParent.SoundDevice().Handle())
   294 		{
   295 		iParent.SoundDevice().CancelPlayData();
   296 		iParent.SoundDevice().FlushPlayBuffer();
   297 		}
   298 	}
   299 	
   300 // CAudioDevice::CInput port class implementation
   301 CAudioDevice::COutputPort::COutputPort(CAudioDevice& aParent) 
   302 	: CActive(EPriorityNormal),
   303 	iParent(aParent),
   304 	iSampleRate(KDefaultSampleRate),
   305 	iChannels(KDefaultNumberChannels),
   306 	iBufferSize(KBufferSize)
   307 	{	
   308 	}
   309 
   310 TInt CAudioDevice::CInputPort::SampleRate()
   311 	{
   312 	return iSampleRate;
   313 	}
   314 	
   315 TInt CAudioDevice::CInputPort::Channels()
   316 	{
   317 	return iChannels;
   318 	}
   319 
   320 void CAudioDevice::CInputPort::MipInitialize()
   321 	{
   322 	// Nothing to do
   323 	}
   324 	
   325 CAudioDevice::COutputPort* CAudioDevice::COutputPort::NewL(CAudioDevice& aParent)
   326 	{
   327 	COutputPort* self = new (ELeave) COutputPort(aParent);
   328 	CleanupStack::PushL(self);
   329 	self->ConstructL();
   330 	CleanupStack::Pop(self);
   331 	return self;
   332 	}
   333 
   334 void CAudioDevice::COutputPort::ConstructL()
   335 	{
   336 	CActiveScheduler::Add(this);	
   337 	}
   338 
   339 TInt CAudioDevice::COutputPort::MopConfigure(const TPuConfig& aConfig)
   340 	{
   341 	if (aConfig.Uid() == TUid::Uid(KUidTTaskConfig))
   342 		{
   343 		const TTaskConfig* config = TPuTaskConfig::GetStructure(aConfig);	
   344 	
   345 		iSampleRate = config->iRate;
   346 		iChannels = (config->iStereoMode & ETaskMono)? 1 : 2;
   347 		iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse;
   348 		return KErrNone;
   349 		}
   350 		
   351 	if (aConfig.Uid() == TUid::Uid(KUidTTaskConfig2))
   352 		{
   353 		const TTaskConfig2* config = TPuTaskConfig2::GetStructure(aConfig);	
   354 	
   355 		iSampleRate = config->iRate;
   356 		iChannels = config->iNumberOfChannels;
   357 		iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse;
   358 		return KErrNone;
   359 		}	
   360 	return KErrNotSupported;
   361 	}
   362 	
   363 TInt CAudioDevice::COutputPort::MopGetConfig(TPuConfig& /*aConfig*/)
   364 	{
   365 	return KErrNotSupported;
   366 	}
   367 
   368 void CAudioDevice::COutputPort::MopInitialize()
   369 	{
   370 	// Nothing to do
   371 	}
   372 
   373 TInt CAudioDevice::COutputPort::MopTunnelRequest(const MMdfInputPort& /*aInputPortToBeConnectedTo*/,
   374 	TTunnelFlags& /*aTunnelFlags*/, TSupplierType& /*aSupplierType*/)
   375 	{
   376 	return KErrNone;
   377 	}
   378 
   379 void CAudioDevice::COutputPort::MopReadData(CMMFBuffer& aOutputBuffer)
   380 	{
   381 	TInt err = iBuffers.Append(&aOutputBuffer);
   382 	if (err == KErrNone)
   383 		{
   384 		if ((iParent.State() == EProcessingUnitExecuting || iParent.State() == EProcessingUnitPaused) && !IsActive())
   385 			{
   386 			SetActive();
   387 			TRequestStatus* status = &iStatus;
   388 			User::RequestComplete(status, KErrNone);	
   389 			}		
   390 		}
   391 	else
   392 		{
   393 		if (iObserver)
   394 			{
   395 			iObserver->MopoReadDataComplete(this, &aOutputBuffer, err);
   396 			}
   397 		}
   398 	}
   399 
   400 TBool CAudioDevice::COutputPort::MopIsTunnelled() const
   401 	{
   402 	return EFalse;	
   403 	}
   404 
   405 TInt CAudioDevice::COutputPort::MopIndex() const
   406 	{
   407 	return KOutputPortIndex;
   408 	}
   409 	
   410 CMMFBuffer* CAudioDevice::COutputPort::MopCreateBuffer(TInt /*aBufferSize*/)
   411 	{
   412 	return NULL;
   413 	}
   414 	
   415 TInt CAudioDevice::COutputPort::MopUseBuffer(CMMFBuffer& /*aBuffer*/) 
   416 	{
   417 	return KErrNone;
   418 	}
   419 
   420 TInt CAudioDevice::COutputPort::MopFreeBuffer(CMMFBuffer* /*aBuffer*/) 
   421 	{
   422 	return KErrNone;
   423 	}
   424 
   425 void CAudioDevice::COutputPort::Execute()
   426 	{
   427 	if (!IsActive() && iBuffers.Count()>0)
   428 		{
   429 		SetActive();
   430 		TRequestStatus* status = &iStatus;
   431 		User::RequestComplete(status, KErrNone);
   432 		}
   433 	}
   434 	
   435 void CAudioDevice::COutputPort::Pause()
   436 	{
   437 	if(iParent.SoundDevice().Handle())
   438 		{
   439 		iParent.SoundDevice().FlushRecordBuffer();
   440 		}	
   441 	}
   442 	
   443 void CAudioDevice::COutputPort::Stop()
   444 	{
   445 	Cancel();
   446 	}
   447 
   448 void CAudioDevice::COutputPort::MopDisconnectTunnel()
   449 	{
   450 	// Find the last buffer in the array and set it as the 'LastBuffer'
   451 	if(iBuffers.Count() > 0)
   452 		{
   453 		(iBuffers[iBuffers.Count() - 1])->SetLastBuffer(ETrue);		
   454 		}
   455 	// Still have to send callback and cancel driver
   456 	iObserver->MopoDisconnectTunnelComplete(this, KErrNone);
   457 	iParent.SoundDevice().CancelRecordData();
   458 	}
   459 	
   460 void CAudioDevice::COutputPort::MopRestartTunnel()
   461 	{
   462 	}
   463 	
   464 TUint32 CAudioDevice::COutputPort::MopBufferSize() const
   465 	{
   466 	return iBufferSize;
   467 	}
   468 	
   469 void CAudioDevice::CInputPort::MipSetObserver(const MMdfInputPortObserver& aObserver)
   470 	{
   471 	iObserver = const_cast<MMdfInputPortObserver*>(&aObserver);
   472 	}
   473 
   474 void CAudioDevice::COutputPort::MopSetObserver(const MMdfOutputPortObserver& aObserver)
   475 	{
   476 	iObserver = const_cast<MMdfOutputPortObserver*>(&aObserver);
   477 	}
   478 
   479 TInt CAudioDevice::COutputPort::MopCreateCustomInterface(TUid aUid)
   480 	{
   481 	if (aUid.iUid == KMmfRecordSettingsCustomInterface)
   482 		{
   483 		return KErrNone;
   484 		}
   485 	return KErrNotSupported;	
   486 	}
   487 	
   488 TAny* CAudioDevice::COutputPort::MopCustomInterface(TUid aUid)
   489 	{
   490 	if (aUid.iUid == KMmfRecordSettingsCustomInterface)
   491 		{
   492 		return dynamic_cast<MRecordCustomInterface*>(this);
   493 		}
   494 
   495 	return NULL;
   496 	}
   497 	
   498 void CAudioDevice::COutputPort::RunL()
   499 	{
   500 	if (iCurrentBuffer != NULL)
   501 		{
   502 		// If we've been signalled with a buffer, callback that we've completed the writing of the
   503 		// buffer
   504 		if (iObserver)
   505 			{		
   506 			TInt length = iCurrentBuffer->BufferSize();
   507 			iBytesRecorded += length;
   508 			if (length<iBufferSize)
   509 				{
   510 				iCurrentBuffer->SetLastBuffer(ETrue);
   511 				iParent.SoundDevice().CancelRecordData(); // Required so that a resume of an encode functions correctly
   512 				}
   513 					
   514 			iObserver->MopoReadDataComplete(this, iCurrentBuffer, iStatus.Int());
   515 			
   516 			}
   517 			iCurrentBuffer = NULL;
   518 		}
   519 		
   520 	if (iStatus == KErrNone)
   521 		{
   522 		if (iBuffers.Count()>0)
   523 			{
   524 			iCurrentBuffer = iBuffers[0];
   525 			iBuffers.Remove(0);
   526 			
   527 			if (CMMFBuffer::IsSupportedDataBuffer(iCurrentBuffer->Type()))
   528 				{
   529 				TDes8& aBufferDes = (static_cast<CMMFDataBuffer*>(iCurrentBuffer))->Data();
   530 				iStatus = KRequestPending;
   531 				iParent.SoundDevice().RecordData(iStatus, aBufferDes);
   532 				SetActive();
   533 				}
   534 			}
   535 		}
   536 	}
   537 
   538 void CAudioDevice::COutputPort::DoCancel()
   539 	{
   540 	if (iParent.SoundDevice().Handle())
   541 		{
   542 		iParent.SoundDevice().CancelRecordData();
   543 		iParent.SoundDevice().FlushRecordBuffer();
   544 		}		
   545 	}
   546 	
   547 TInt CAudioDevice::COutputPort::SampleRate()
   548 	{
   549 	return iSampleRate;
   550 	}
   551 	
   552 TInt CAudioDevice::COutputPort::Channels()
   553 	{
   554 	return iChannels;
   555 	}
   556 
   557 CAudioDevice::COutputPort::~COutputPort()
   558 	{
   559 	Cancel();
   560 	iBuffers.Close();
   561 	}
   562 	
   563 // from MRecordCustomInterface
   564 void CAudioDevice::COutputPort::SetGain(TUint aGain)
   565 	{
   566 	iGain = aGain;
   567 	}
   568 TUint CAudioDevice::COutputPort::Gain()
   569 	{
   570 	return iGain;
   571 	}
   572 	
   573 TUint CAudioDevice::COutputPort::BytesRecorded()
   574 	{
   575 	return iBytesRecorded;
   576 	}
   577 
   578 // ------------------------------------------------------------------------------------------
   579 // CAudioDevice Implementation
   580 
   581 
   582 CAudioDevice::CAudioDevice()
   583 	{
   584 	}
   585 	
   586 CAudioDevice::~CAudioDevice()
   587 	{
   588 	delete iInputPort;
   589 	delete iOutputPort;
   590 	iSoundDevice.Close();
   591 	}
   592 
   593 void CAudioDevice::Execute()
   594 	{
   595 	__ASSERT_ALWAYS(iObserver, User::Panic(KAudioDevicePanic, EObserverNotSet));
   596 	TInt err = KErrNone;
   597 	if(!iSoundDevice.Handle())
   598 		{
   599 		err = iSoundDevice.Open();
   600 		}
   601 	
   602 	RMdaDevSound::TCurrentSoundFormatBuf buf;
   603 	if (err == KErrNone)
   604 		{
   605 		if(iState == EProcessingUnitPaused)
   606 			{
   607 			iSoundDevice.ResumePlaying();
   608 			}
   609 		else
   610 			{
   611 			// Set play format (for input port)
   612 			iSoundDevice.GetPlayFormat(buf);
   613 			buf().iRate = iInputPort->SampleRate();
   614 			buf().iChannels = iInputPort->Channels();
   615 			buf().iBufferSize = KBufferSize;
   616 			buf().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
   617 			err = iSoundDevice.SetPlayFormat(buf);
   618 			}
   619 		}
   620 	iState = EProcessingUnitExecuting;	
   621 	if (err == KErrNone)
   622 		{
   623 		// Set record format (for output format)
   624 		iSoundDevice.GetRecordFormat(buf);
   625 		buf().iRate = iOutputPort->SampleRate();
   626 		buf().iChannels = iOutputPort->Channels();
   627 		buf().iBufferSize = KBufferSize;
   628 		buf().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
   629 		iSoundDevice.SetRecordFormat(buf);
   630 		iInputPort->Execute();
   631 		iOutputPort->Execute();
   632 		}
   633 	else 
   634 		{
   635 		iObserver->ExecuteComplete(this, err);
   636 		}		
   637 	}
   638 
   639 TInt CAudioDevice::Pause()
   640 	{
   641 	iState = EProcessingUnitPaused;
   642 	iInputPort->Pause();
   643 	iOutputPort->Pause();
   644 	return KErrNone;
   645 	}
   646 
   647 void CAudioDevice::Stop()
   648 	{
   649 	if(iState == EProcessingUnitExecuting || iState == EProcessingUnitPaused)
   650 		{
   651 		// Cancel and flush the device driver		
   652 		iInputPort->Stop();
   653 		iOutputPort->Stop();
   654 		iState = EProcessingUnitIdle;
   655 		
   656 		// Close the sound device
   657 		iSoundDevice.Close();	
   658 		}		
   659 	}
   660 	
   661 CAudioDevice* CAudioDevice::NewL()
   662 	{
   663 	CAudioDevice* self = new (ELeave) CAudioDevice;
   664 	CleanupStack::PushL(self);
   665 	self->ConstructL();
   666 	CleanupStack::Pop(self);
   667 	return self;
   668 	}
   669 	
   670 TInt CAudioDevice::Create(const MMdfProcessingUnitObserver& aObserver)
   671 	{
   672 	iObserver = const_cast<MMdfProcessingUnitObserver*>(&aObserver);
   673 	return KErrNone;
   674 	}
   675 	
   676 TInt CAudioDevice::Configure(const TPuConfig& /*aConfigurationSetup*/)
   677 	{
   678 	return KErrNotSupported;
   679 	}
   680 	
   681 TInt CAudioDevice::GetConfig(TPuConfig& /*aConfigurationSetup*/)
   682 	{
   683 	return KErrNotSupported;
   684 	}
   685 
   686 TInt CAudioDevice::GetInputPorts(RPointerArray<MMdfInputPort>& aComponentInputPorts )
   687 	{
   688 	return aComponentInputPorts.Append(iInputPort);
   689 	}
   690 
   691 TInt CAudioDevice::GetOutputPorts(RPointerArray<MMdfOutputPort>& aComponentOutputPorts )
   692 	{
   693 	return aComponentOutputPorts.Append(iOutputPort);
   694 	}
   695 
   696 void CAudioDevice::ConstructL()
   697 	{
   698 	iInputPort = CInputPort::NewL(*this);
   699 	iOutputPort = COutputPort::NewL(*this);
   700 	iState = EProcessingUnitLoaded;
   701 	}
   702 
   703 void CAudioDevice::Initialize()
   704 	{
   705 	__ASSERT_ALWAYS(iObserver, User::Panic(KAudioDevicePanic, EObserverNotSet));
   706 	
   707 	iObserver->InitializeComplete(this, KErrNone);
   708 	iState = EProcessingUnitIdle;
   709 	}
   710 
   711 MMdfProcessingUnitObserver* CAudioDevice::Observer()
   712 	{
   713 	return iObserver;	
   714 	}
   715 		
   716 TProcessingUnitState CAudioDevice::State()
   717 	{
   718 	return iState;	
   719 	}
   720 		
   721 RMdaDevSound& CAudioDevice::SoundDevice()
   722 	{
   723 	return iSoundDevice;
   724 	}
   725 	
   726 TAny* CAudioDevice::CustomInterface(TUid /*aUid*/)
   727 	{
   728 	return NULL;
   729 	}
   730 		
   731 TInt CAudioDevice::CreateCustomInterface(TUid /*aUid*/)
   732 	{
   733 	return KErrNotSupported;
   734 	}
   735 
   736 // ------------------------------------------------------------------------------------------	
   737 // ECOM Implementation table entry	
   738 	
   739 const TImplementationProxy ImplementationTable[] = 
   740 	{
   741 	IMPLEMENTATION_PROXY_ENTRY(KUidPUAudioDevice,	CAudioDevice::NewL),
   742 	};
   743 
   744 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
   745 	{
   746 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
   747 	return ImplementationTable;
   748 	}
   749