mmhais/refacladapt/src/audiostream/audiostream.cpp
changeset 0 40261b775718
child 54 b68f3e90dca1
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     1 //audiostream.cpp
       
     2 
       
     3 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 // All rights reserved.
       
     5 // This component and the accompanying materials are made available
       
     6 // under the terms of "Eclipse Public License v1.0"
       
     7 // which accompanies this distribution, and is available
       
     8 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     9 //
       
    10 // Initial Contributors:
       
    11 // Nokia Corporation - initial contribution.
       
    12 //
       
    13 // Contributors:
       
    14 //
       
    15 // Description:
       
    16 //
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include <a3f/a3fbase.h>
       
    22 #include <a3f/audioprocessingunittypeuids.h>
       
    23 #include <a3f/a3ffourcclookup.h>
       
    24 
       
    25 #include "audiostream.h"
       
    26 
       
    27 // PHYSICAL COMPONENTS
       
    28 #include "audiocodec.h"
       
    29 #include "audiostream.h"
       
    30 #include "buffersource.h"
       
    31 #include "buffersink.h"
       
    32 #include "audiodevicesource.h"
       
    33 #include "audiodevicesink.h"
       
    34 #include "audiogaincontrol.h"
       
    35 #include "maudiostreamadaptationobserver.h"
       
    36 
       
    37 #include <a3f/maudiodatasupplier.h>
       
    38 #include <a3f/maudiodataconsumer.h>
       
    39 
       
    40 #include "minputport.h"
       
    41 #include "moutputport.h"
       
    42 #include "audiocontext.h"
       
    43 
       
    44 #include <ecom/implementationproxy.h>
       
    45 
       
    46 
       
    47 
       
    48 const TInt KSampleRate8000Hz = 8000;
       
    49 
       
    50 // Map the interface implementation UIDs to implementation factory functions
       
    51 const TImplementationProxy ImplementationTable[] =
       
    52 	{
       
    53 	IMPLEMENTATION_PROXY_ENTRY(0x10283461,  CAudioStream::NewL),
       
    54 	};
       
    55 
       
    56 
       
    57 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
    58 	{
       
    59 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
    60 	return ImplementationTable;
       
    61 	}
       
    62 
       
    63 // ---------------------------------------------------------------------------
       
    64 // Constructor
       
    65 // ---------------------------------------------------------------------------
       
    66 //
       
    67 CAudioStream::CAudioStream()
       
    68 	: iCurrentStreamState(EUninitialized), 
       
    69 	iDesiredStreamState(EUninitialized)
       
    70 	{
       
    71 	TRACE_CREATE();
       
    72 	DP_CONTEXT(CAudioStream::CAudioStream *CD1*, CtxDevSound, DPLOCAL);
       
    73 	DP_IN();
       
    74 	// Some init config values
       
    75 	iSampleRateConfig = KSampleRate8000Hz;
       
    76 	iModeConfig = KA3FModeMono;
       
    77 	
       
    78 	DP_OUT();
       
    79 	}
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // Factory method
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 CAudioStream* CAudioStream::NewL()
       
    86 	{
       
    87 	DP_STATIC_CONTEXT(CAudioStream::NewL *CD0*, CtxDevSound, DPLOCAL);
       
    88 	DP_IN();
       
    89 	CAudioStream* self = new(ELeave)CAudioStream();
       
    90 	CleanupStack::PushL(self);
       
    91 	self->ConstructL();
       
    92 	CleanupStack::Pop(self);
       
    93 	DP0_RET(self, "0x%x");
       
    94 	}
       
    95 
       
    96 // ---------------------------------------------------------------------------
       
    97 // Second phase constructor
       
    98 // ---------------------------------------------------------------------------
       
    99 //
       
   100 void CAudioStream::ConstructL()
       
   101 	{
       
   102 	DP_CONTEXT(CAudioStream::ConstructL *CD1*, CtxDevSound, DPLOCAL);
       
   103 	DP_IN();
       
   104 	DP_OUT();
       
   105 	}
       
   106 
       
   107 // ---------------------------------------------------------------------------
       
   108 // Destructor
       
   109 // ---------------------------------------------------------------------------
       
   110 //
       
   111 CAudioStream::~CAudioStream()
       
   112 	{
       
   113 	DP_CONTEXT(CAudioStream::~CAudioStream *CD1*, CtxDevSound, DPLOCAL);
       
   114 	DP_IN();
       
   115 
       
   116 	iAudioStreamObservers.Close();
       
   117 	iAudioCodecObservers.Close();
       
   118 	// Just for now
       
   119 	DeletePhysicalComponents();
       
   120 	REComSession::FinalClose();
       
   121 	DP_OUT();
       
   122 	}
       
   123 
       
   124 // ---------------------------------------------------------------------------
       
   125 // CAudioStream::RegisterAudioStreamObserver
       
   126 // ---------------------------------------------------------------------------
       
   127 //
       
   128 TInt CAudioStream::RegisterAudioStreamObserver(MAudioStreamAdaptationObserver& aObserver)
       
   129 	{
       
   130 	DP_CONTEXT(CAudioStream::RegisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL);
       
   131 	DP_IN();
       
   132 	TInt err = iAudioStreamObservers.Find(&aObserver);
       
   133 	if(err == KErrNotFound)
       
   134 		{
       
   135 		err = iAudioStreamObservers.Append(&aObserver);
       
   136 		}
       
   137 	else
       
   138 		{
       
   139 		err = KErrAlreadyExists;
       
   140 		}
       
   141 	DP0_RET(err, "%d");
       
   142 	}
       
   143 
       
   144 // ---------------------------------------------------------------------------
       
   145 // CAudioStream::UnregisterAudioStreamObserver
       
   146 // ---------------------------------------------------------------------------
       
   147 //
       
   148 void CAudioStream::UnregisterAudioStreamObserver(MAudioStreamAdaptationObserver& aObserver)
       
   149 	{
       
   150 	DP_CONTEXT(CAudioStream::UnregisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL);
       
   151 	DP_IN();
       
   152 	TInt idxOrErr = iAudioStreamObservers.Find(&aObserver);
       
   153 	if( idxOrErr != KErrNotFound )
       
   154 		{
       
   155 		iAudioStreamObservers.Remove(idxOrErr);
       
   156 		}
       
   157 	DP_OUT();
       
   158 	}
       
   159 
       
   160 
       
   161 // ---------------------------------------------------------------------------
       
   162 // CAudioStream::SetFourCC
       
   163 // ---------------------------------------------------------------------------
       
   164 //
       
   165 void CAudioStream::SetFourCC(const CFourCCConvertor& aFourCCConvertor)
       
   166 	{
       
   167 	DP_CONTEXT(CAudioStream::SetFourCC *CD1*, CtxDevSound, DPLOCAL);
       
   168 	DP_IN();
       
   169 	CFourCCConvertor& ref = const_cast<CFourCCConvertor&>(aFourCCConvertor);
       
   170 	iFourCCConvertor = static_cast<CFourCCConvertor*>(static_cast<TAny*>(&ref));
       
   171 	DP_OUT();
       
   172 	}
       
   173 
       
   174 
       
   175 // ---------------------------------------------------------------------------
       
   176 // CAudioStream::UnregisterAudioStreamObserver
       
   177 // ---------------------------------------------------------------------------
       
   178 //
       
   179 void CAudioStream::UnregisterAllAudioStreamObserver()
       
   180 	{
       
   181 	DP_CONTEXT(CAudioStream::UnregisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL);
       
   182 	DP_IN();
       
   183 	
       
   184 	iAudioStreamObservers.Reset();
       
   185 	
       
   186 	DP_OUT();
       
   187 	}
       
   188 
       
   189 
       
   190 // ---------------------------------------------------------------------------
       
   191 // MMRC extension mechanism
       
   192 // ---------------------------------------------------------------------------
       
   193 TAny* CAudioStream::GetComponent(TUid aType)
       
   194 	{
       
   195 	TAny* ptr = NULL;
       
   196 	MLogicalChain* clientDesiredChain = NULL;
       
   197 	CAudioContext* context = static_cast<CAudioContext*>(iAudioContext);
       
   198 	if(context)
       
   199 		{
       
   200 		clientDesiredChain = context->GetLogicalChain(0);	
       
   201 		}
       
   202 	if (clientDesiredChain)
       
   203 		{
       
   204 		ptr = clientDesiredChain->GetComponent(aType);
       
   205 		}
       
   206 	return ptr;
       
   207 	}
       
   208 	
       
   209 // ---------------------------------------------------------------------------
       
   210 // CAudioStream::Message
       
   211 // ---------------------------------------------------------------------------
       
   212 TInt CAudioStream::Message(MLogicalChain& aCurrentChain, MLogicalChain& aDesiredChain, MAudioContext& aContext, TInt aFlags)
       
   213 	{
       
   214 	DP_CONTEXT(CAudioStream::Message *CD0*, CtxDevSound, DPLOCAL);
       
   215 	DP_IN();
       
   216 	TInt err = KErrNone;
       
   217 
       
   218 	iCurrentChain = &aCurrentChain;
       
   219 	iDesiredChain = &aDesiredChain;
       
   220 
       
   221 	TUint messageType = aDesiredChain.MessageType();
       
   222 
       
   223 	iAudioContext = &aContext;
       
   224 
       
   225 	CAudioContext* audioContext = static_cast<CAudioContext*> (iAudioContext);
       
   226 	// TO NOTIFY DIRECTLY CONTEXT
       
   227 	MMultimediaResourceControlObserver* mmrcObserver = static_cast<MMultimediaResourceControlObserver*>(audioContext);
       
   228 
       
   229 	// Register stream observer
       
   230 	if (messageType & ERegisterStreamObserver != 0)
       
   231 		{
       
   232 		// Use MMRC extension mechanism
       
   233 		TAny* ptr = GetComponent(KUidAudioStreamAdaptationObserver);	
       
   234 		MAudioStreamAdaptationObserver* observer = static_cast<MAudioStreamAdaptationObserver*>(ptr);
       
   235 		if(observer)
       
   236 			{
       
   237 			err = RegisterAudioStreamObserver(*observer);	
       
   238 			}
       
   239 		}
       
   240 	
       
   241 	// Register codec observer
       
   242 	if (messageType & ERegisterCodecObserver != 0)
       
   243 		{
       
   244 		// Use MMRC extension mechanism
       
   245 		TAny* ptr = GetComponent(KUidAudioCodecObserver);
       
   246 		MAudioCodecObserver* observer = static_cast<MAudioCodecObserver*>(ptr);
       
   247 		if (observer) 
       
   248 			{
       
   249 			err = RegisterAudioCodecObserver(*observer);	
       
   250 			}
       
   251 		}
       
   252 
       
   253 	// Component creation
       
   254 	TUint bit = messageType & EComponentCreation;
       
   255 	if( (err == KErrNone) && (bit != 0) )
       
   256 		{
       
   257 		CAudioContext* context = static_cast<CAudioContext*>(iAudioContext);
       
   258 		MLogicalChain* clientDesiredChain = context->GetLogicalChain(0);	
       
   259 		err = CreatePhysicalComponents(*clientDesiredChain);
       
   260 
       
   261 		// For Configuration
       
   262 		if (err==KErrNone)
       
   263 			{
       
   264 			clientDesiredChain->SetAdaptationStream(*this);
       
   265 			clientDesiredChain->SetStreamBufferControl(*this);
       
   266 			}
       
   267 		}
       
   268 	
       
   269 	// Component alteration
       
   270 	// Changes that must be applied before stream state transition
       
   271 	TBool configCodec = EFalse;
       
   272 	bit = messageType & EComponentAlterationCodec;
       
   273 	if( (err == KErrNone) && (bit != 0) )
       
   274 		{
       
   275 		// Set Format
       
   276 		if(iCodec)
       
   277 			{
       
   278 			TUid desiredCodecFormat  = iDesiredChain->CodecFormat();
       
   279 			err = iCodec->SetFormat( desiredCodecFormat );
       
   280 			} 
       
   281 		
       
   282 		if(err == KErrNone)
       
   283 			{
       
   284 			//if samplerate or mode has changed, update value and trigger callbacks at appropriate point
       
   285 			if ((iDesiredChain->GetSampleRate() > 0) && (iDesiredChain->GetSampleRate() != iSampleRateConfig))
       
   286 				{
       
   287 				iSampleRateConfig = iDesiredChain->GetSampleRate();
       
   288 				configCodec = ETrue;
       
   289 				}
       
   290 			if ((iDesiredChain->GetMode() != KNullUid) && (iDesiredChain->GetMode() != iModeConfig))
       
   291 				{
       
   292 				iModeConfig  = iDesiredChain->GetMode();
       
   293 				configCodec = ETrue;
       
   294 				}
       
   295 			}
       
   296 		}
       
   297 
       
   298 
       
   299 	bit = messageType & EComponentAlterationGain;
       
   300 	if( (err == KErrNone) && (bit != 0) )
       
   301 		{
       
   302 		// Apply volume ramp
       
   303 		// Note that ramp operation and gain now are applied separately because current tone arquitecture 
       
   304 		// need the volume ramp to be set before start the tonehwdevice 
       
   305 		TTimeIntervalMicroSeconds currentRampTimeValue = 0; 
       
   306 		TUid currentRampTimeOperation(KNullUid);
       
   307 		TTimeIntervalMicroSeconds desiredRampTimeValue = 0; 
       
   308 		TUid desiredRampTimeOperation(KNullUid);
       
   309 		iCurrentChain->GetVolumeRampParameters(currentRampTimeOperation, currentRampTimeValue);
       
   310 		iDesiredChain->GetVolumeRampParameters(desiredRampTimeOperation, desiredRampTimeValue);
       
   311 		
       
   312 		if(currentRampTimeOperation != desiredRampTimeOperation ||
       
   313 		currentRampTimeValue.Int64() != desiredRampTimeValue.Int64() )
       
   314 			{
       
   315 			if (iGainControl)
       
   316 				{
       
   317 				err = iGainControl->ConfigureRamp(desiredRampTimeOperation, desiredRampTimeValue);
       
   318 				}
       
   319 			}
       
   320 		}
       
   321 
       
   322 	//Configuration request
       
   323 	// Stream state
       
   324 	TBool invokeStateEventCallback = EFalse;
       
   325 	iDesiredStreamState = iDesiredChain->StreamState();
       
   326 	if( (err == KErrNone) && (iCurrentStreamState != iDesiredStreamState) )
       
   327 		{
       
   328 		err = ChangeState(iCurrentStreamState, iDesiredStreamState);
       
   329 		if (err == KErrNone)
       
   330 			{
       
   331 			iCurrentStreamState = iDesiredStreamState;
       
   332 			}
       
   333 		invokeStateEventCallback = ETrue;
       
   334 		}
       
   335 
       
   336 	// Component alteration
       
   337 	// Changes that must be applied after stream state transition
       
   338 	TBool gainUpdated = EFalse;
       
   339 	bit = messageType & EComponentAlterationGain;
       
   340 	if( (err == KErrNone) && (bit != 0) )
       
   341 		{
       
   342 		TAny* ptr = GetComponent(KUidAudioGainControl);
       
   343 		MAudioGainControl* gaincontrol = static_cast<MAudioGainControl*>(ptr);
       
   344 		if (iGainControl && gaincontrol)
       
   345 			{
       
   346 			RArray<TAudioChannelGain> channels;
       
   347 			TInt err = gaincontrol->GetGain(channels);
       
   348 			if (channels.Count() != 0 )
       
   349 				{
       
   350 				err = iGainControl->SetGain(channels);
       
   351 				gainUpdated = ETrue;
       
   352 				}
       
   353 			channels.Close();
       
   354 			}
       
   355 		}
       
   356 	
       
   357 	TBool invokeCodecCallbacks = EFalse;
       
   358 	bit = messageType & EComponentAlterationCodec;
       
   359 	if ( (err == KErrNone) && (bit != 0) && configCodec && (iCurrentStreamState == EInitialized) )
       
   360 		{
       
   361 		//codec loading actually configures sample rate and mode
       
   362 		ASSERT(iCodec);
       
   363 		err = iCodec->Load(iSampleRateConfig, iModeConfig);
       
   364 		iIsCodecConfig = (err == KErrNone);
       
   365 		invokeCodecCallbacks = ETrue;
       
   366 		if ( err != KErrNone )
       
   367 			{
       
   368 			//get back to previous values in case of error
       
   369 			iSampleRateConfig = iCurrentChain->GetSampleRate();
       
   370 			iModeConfig = iCurrentChain->GetMode();
       
   371 			}
       
   372 		}
       
   373 
       
   374 	// Component destruction
       
   375 	bit = messageType & EComponentDestruction;
       
   376 	if( (err == KErrNone) && (bit != 0) )
       
   377 		{
       
   378 		DeletePhysicalComponents();
       
   379 		}
       
   380 
       
   381 	TUint isStopping = aFlags & KServerStopping;
       
   382 	TUint preemptionRequest = aFlags & KPreemptionRequest;
       
   383 
       
   384 	// HERE WE CAN GUARANTEE THAT THE REQUEST IS SUCCESFUL
       
   385 	// Notify context 
       
   386 	// 1ST CALLBACK
       
   387 	if(!preemptionRequest) 
       
   388 		{
       
   389 		mmrcObserver->ReceiveResourceUpdate(&aDesiredChain, KErrNone);
       
   390 		}
       
   391 	else 
       
   392 		{
       
   393 		mmrcObserver->ReceivePreemptionUpdate(&aDesiredChain, err);
       
   394 		}
       
   395 
       
   396 	// Processing unit callbacks
       
   397 	// Gain control
       
   398 	// Note that due to error checking before applying any change 
       
   399 	// this callback always returned the error obtained by calling SetGain
       
   400 	// or KErrNone
       
   401 	if(gainUpdated)
       
   402 		{
       
   403 		if (iGainControl)
       
   404 			{
       
   405 			iGainControl->IssueGainChangedCallBack(err);
       
   406 			}
       
   407 		}
       
   408 
       
   409 	// Stream 
       
   410 	if(invokeStateEventCallback)
       
   411 		{
       
   412 		invokeStateEventCallback = EFalse;
       
   413 		for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ )
       
   414 			{
       
   415 			if ( !isStopping )
       
   416 				{
       
   417 				iAudioStreamObservers[idx]->StateEvent(err, iCurrentStreamState);
       
   418 				}
       
   419 			}
       
   420 		}
       
   421 	if( invokeCodecCallbacks && (iCurrentStreamState == EInitialized) )
       
   422 		{
       
   423 		TInt count = iAudioCodecObservers.Count();
       
   424 		for ( TInt idx = 0; idx < count; idx++ )
       
   425 			{
       
   426 			//TODO replace this functionality with the new mmrc
       
   427 			iAudioCodecObservers[idx]->SampleRateSet(err);
       
   428 			iAudioCodecObservers[idx]->ModeSet(err);
       
   429 			}
       
   430 		}
       
   431 
       
   432 	// Now has no effect on context
       
   433 	// But it's needed to let the MMRC know about the operation being completed
       
   434 	// and in such way let it to know that 
       
   435 	for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ )
       
   436 		{
       
   437 		if ( !isStopping )
       
   438 			{
       
   439 			iAudioStreamObservers[idx]->PhysicalAdaptationEvent(EOperationComplete, err);
       
   440 			}
       
   441 		}
       
   442 
       
   443 	// Don't need to send last callback sync
       
   444 	// Let MMRC do it
       
   445 
       
   446 	DP0_RET(err, "%d");
       
   447 	}
       
   448 
       
   449 // ---------------------------------------------------------------------------
       
   450 // CAudioStream::DeletePhysicalComponents
       
   451 // ---------------------------------------------------------------------------
       
   452 void CAudioStream::DeletePhysicalComponents()
       
   453 	{
       
   454 	DP_CONTEXT(CAudioStream::DeletePhysicalComponents *CD0*, CtxDevSound, DPLOCAL);
       
   455 	DP_IN();
       
   456 	if(iBufferSource)
       
   457 		{
       
   458 		delete iBufferSource;
       
   459 		iBufferSource = NULL;
       
   460 		}
       
   461 	if(iBufferSink)
       
   462 		{
       
   463 		delete iBufferSink;
       
   464 		iBufferSink = NULL;
       
   465 		}
       
   466 	if(iCodec)
       
   467 		{
       
   468 		delete iCodec;
       
   469 		iCodec = NULL;
       
   470 		iIsCodecConfig = EFalse;
       
   471 		}
       
   472 	if(iGainControl)
       
   473 		{
       
   474 		delete iGainControl;
       
   475 		iGainControl = NULL;
       
   476 		}
       
   477 	if(iDeviceSource)
       
   478 		{
       
   479 		delete iDeviceSource;
       
   480 		iDeviceSource = NULL;
       
   481 		}
       
   482 	if(iDeviceSink)
       
   483 		{
       
   484 		delete iDeviceSink;
       
   485 		iDeviceSink= NULL;
       
   486 		}
       
   487 	DP_OUT();
       
   488 	}
       
   489 
       
   490 
       
   491 // ---------------------------------------------------------------------------
       
   492 // CAudioStream::CreatePhysicalComponents
       
   493 // ---------------------------------------------------------------------------
       
   494 TInt CAudioStream::CreatePhysicalComponents(MLogicalChain& aDesiredChain)
       
   495 	{
       
   496 	DP_CONTEXT(CAudioStream::CreatePhysicalComponents *CD0*, CtxDevSound, DPLOCAL);
       
   497 	DP_IN();
       
   498 	
       
   499 	TInt err = KErrNone;
       
   500 	TInt units = aDesiredChain.AudioProcessingUnitsCount();
       
   501 	TInt index=0;
       
   502 	TUid typeId;
       
   503 
       
   504 	for (index=0; index < units ; index++)
       
   505 		{
       
   506 		typeId = aDesiredChain.AudioProcessingUnitUid(index);
       
   507 
       
   508 		// By the moment all components 
       
   509 		if (err == KErrNone)
       
   510 			{
       
   511 			if (typeId == KUidAudioDecoder || typeId == KUidAudioEncoder )
       
   512 				{
       
   513 				if(!iCodec)
       
   514 					{
       
   515 					TRAP(err, iCodec = CAudioCodec::NewL(typeId, *iFourCCConvertor ));
       
   516 					iIsCodecConfig = EFalse;
       
   517 					iCodec->RegisterAudioCodecObserver(*this);
       
   518 					TAny* ptr = GetComponent(KUidAudioCodecAdaptationObserver);
       
   519 					MAudioCodecAdaptationObserver* observer = static_cast<MAudioCodecAdaptationObserver*>(ptr);
       
   520 					if(observer)
       
   521 						{
       
   522 						iCodec->RegisterAudioCodecObserver(*observer);
       
   523 						}
       
   524 					// For HW custom interface
       
   525 					aDesiredChain.SetCustomInterfaceProvider(*iCodec);
       
   526 					}
       
   527 				if(iGainControl)
       
   528 					{
       
   529 					iGainControl->SetHelper(*iCodec);
       
   530 					}
       
   531 				// This mechanism is temporary and must  be replaced
       
   532 				// with the Extension mechanism when the MMRC server
       
   533 				aDesiredChain.SetStreamPositionControl(*iCodec);
       
   534 				}
       
   535 			else if (typeId == KUidMmfBufferSource)
       
   536 				{
       
   537 				if(!iBufferSource)
       
   538 					{
       
   539 					TRAP(err,iBufferSource = CBufferSource::NewL());
       
   540 					// This mechanism is temporary and must  be replaced
       
   541 					// with the Extension mechanism when the MMRC server
       
   542 					aDesiredChain.SetAdaptationSource(*iBufferSource);
       
   543 					/*
       
   544 					TAny* ptr = aDesiredChain.GetComponent(KUidMmfBufferSource);
       
   545 					MMMFAudioDataSupplier* supplier = static_cast<MMMFAudioDataSupplier*>(ptr);
       
   546 					if(supplier)
       
   547 						{
       
   548 						iBufferSource->SetDataSupplier(*supplier);
       
   549 						}
       
   550 					*/
       
   551 					}
       
   552 				}
       
   553 			else if (typeId == KUidMmfBufferSink)
       
   554 				{
       
   555 				if(!iBufferSink)
       
   556 					{
       
   557 					TRAP(err, iBufferSink = CBufferSink::NewL());
       
   558 					// This mechanism is temporary and must  be replaced
       
   559 					// with the Extension mechanism when the MMRC server
       
   560 					aDesiredChain.SetAdaptationSink(*iBufferSink);
       
   561 					}
       
   562 				}
       
   563 			else if (typeId == KUidAudioGainControl)
       
   564 				{
       
   565 				if(!iGainControl)
       
   566 					{
       
   567 					// This mechanism is temporary and must  be replaced
       
   568 					// with the Extension mechanism when the MMRC server
       
   569 					TRAP(err, iGainControl = CAudioGainControl::NewL());
       
   570 					aDesiredChain.SetAdaptationGainControl(*iGainControl);
       
   571 					}
       
   572 				}
       
   573 			else if (typeId == KUidAudioDeviceSink)
       
   574 				{
       
   575 				if(!iDeviceSink)
       
   576 					{
       
   577 					TRAP(err, iDeviceSink = CAudioDeviceSink::NewL());
       
   578 					}
       
   579 				}
       
   580 			else if (typeId == KUidAudioDeviceSource)
       
   581 				{
       
   582 				if(!iDeviceSource)
       
   583 					{
       
   584 					TRAP(err, iDeviceSource = CAudioDeviceSource::NewL());
       
   585 					}
       
   586 				}
       
   587 			else
       
   588 				{
       
   589 				err = KErrNotSupported;
       
   590 				}
       
   591 			}
       
   592 		
       
   593 		// Notify the observers
       
   594 		for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ )
       
   595 			{
       
   596 			iAudioStreamObservers[idx]->AddProcessingUnitComplete(typeId, err);
       
   597 			}
       
   598 		}
       
   599 	DP0_RET(err, "%d");
       
   600 	}
       
   601 
       
   602 // ---------------------------------------------------------------------------
       
   603 // CAudioStream::CreateDataPath
       
   604 // ---------------------------------------------------------------------------
       
   605 TInt CAudioStream::CreateDataPath()
       
   606 	{
       
   607 	DP_CONTEXT(CAudioStream::CreateDataPath *CD1*, CtxDevSound, DPLOCAL);
       
   608 	DP_IN();
       
   609 	TInt err(KErrNotReady);
       
   610 
       
   611 	if(iBufferSource && iCodec) // && iSink && iGain)
       
   612 		{
       
   613 		// TMode == Decode
       
   614 		if(KErrNone == iBufferSource->GetOutputPort(iOutputport) && KErrNone == iCodec->GetInputPort(iInputport))
       
   615 			{
       
   616 			iOutputport->SetInput(iInputport);
       
   617 			iInputport->SetOutput(iOutputport);
       
   618 			err = KErrNone;
       
   619 			}
       
   620 		}
       
   621 	else if(iBufferSink && iCodec) // && iSink && iGain)
       
   622 		{
       
   623 		//TMode == Encode
       
   624 		if(KErrNone == iCodec->GetOutputPort(iOutputport)  && KErrNone == iBufferSink->GetInputPort(iInputport))
       
   625 			{
       
   626 			iOutputport->SetInput(iInputport);
       
   627 			iInputport->SetOutput(iOutputport);
       
   628 			err = KErrNone;
       
   629 			}
       
   630 		}
       
   631 	DP0_RET(err, "%d");
       
   632 	}
       
   633 
       
   634 // ---------------------------------------------------------------------------
       
   635 // CAudioStream::DemolishDataPath
       
   636 // ---------------------------------------------------------------------------
       
   637 //
       
   638 TInt CAudioStream::DemolishDataPath()
       
   639 	{
       
   640 	DP_CONTEXT(CAudioStream::DemolishDataPath *CD1*, CtxDevSound, DPLOCAL);
       
   641 	DP_IN();
       
   642 	iOutputport->RemoveInput(iInputport);
       
   643 	iInputport->RemoveOutput(iOutputport);
       
   644 	DP0_RET(KErrNone, "%d");
       
   645 	}
       
   646 
       
   647 // ---------------------------------------------------------------------------
       
   648 // CAudioStream::ChangeState
       
   649 // ---------------------------------------------------------------------------	
       
   650 TInt CAudioStream::ChangeState(TAudioState aPreviousState, TAudioState aDesiredState)
       
   651 	{
       
   652 	DP_CONTEXT(CAudioStream::ChangeState *CD1*, CtxDevSound, DPLOCAL);
       
   653 	DP_IN();
       
   654 	TInt err(KErrNone);
       
   655 	iCurrentStreamState = aPreviousState;
       
   656 	iDesiredStreamState = aDesiredState;
       
   657 
       
   658 	switch (iDesiredStreamState)
       
   659 		{
       
   660 		case EInitialized:
       
   661 			{
       
   662 			if (iCurrentStreamState == EUninitialized) //Initialize
       
   663 				{
       
   664 				err = CreateDataPath();
       
   665 				if(err == KErrNone)
       
   666 					{
       
   667 					err = iCodec->Initialize();
       
   668 					}
       
   669 				}
       
   670 			else if( iCurrentStreamState == EIdle ) //codec unload (actually, unconfig)
       
   671 				{
       
   672 				iIsCodecConfig = EFalse;
       
   673 				err = KErrNone;
       
   674 				}
       
   675 			// Preemption 
       
   676 			// This A3F adaptation allows going from Active/Primed directly to initialised
       
   677 			// otherwise reference MMRC would need to handle those transitions separately 
       
   678 			else if(iCurrentStreamState == EActive || iCurrentStreamState == EPrimed) 
       
   679 				{
       
   680 				// To Idle 
       
   681 				err = iCodec->Stop();
       
   682 				// To Initilised
       
   683 				iIsCodecConfig = EFalse;
       
   684 				}
       
   685 				
       
   686 			if(err == KErrNone)
       
   687 				{
       
   688 				iCurrentStreamState = EInitialized;
       
   689 				}
       
   690 			break;
       
   691 			}
       
   692 		case EIdle:
       
   693 			{
       
   694 			if ( (iCurrentStreamState == EInitialized) && !iIsCodecConfig )
       
   695 				{
       
   696 				//codec loading actually configures sample rate and mode
       
   697 				err = iCodec->Load(iSampleRateConfig, iModeConfig);
       
   698 				iIsCodecConfig = (err == KErrNone);
       
   699 				}
       
   700 			else if (iCurrentStreamState == EActive)
       
   701 				{
       
   702 				err = iCodec->Stop();
       
   703 				}
       
   704 			else if (iCurrentStreamState == EPrimed)
       
   705 				{
       
   706 				err = iCodec->Stop();
       
   707 				}
       
   708 
       
   709 			if(err == KErrNone)
       
   710 				{
       
   711 				iTimeProcessed = 0;
       
   712 				iCurrentStreamState = EIdle;
       
   713 				}
       
   714 			break;
       
   715 			}
       
   716 		case EPrimed:
       
   717 			{
       
   718 			if (iCurrentStreamState == EIdle)
       
   719 				{
       
   720 				DP0(DLINFO,"==============  Stream is going from EIdle -> PRIMED");
       
   721 				DP0(DLINFO,"Nothing to be done");
       
   722 				}
       
   723 			else if (iCurrentStreamState == EActive)
       
   724 				{
       
   725 				DP0(DLINFO,"============== Stream is going from EActive -> PRIMED");
       
   726 				err = iCodec->Pause();
       
   727 				}
       
   728 			if(err == KErrNone)
       
   729 				{
       
   730 				iCurrentStreamState = EPrimed;
       
   731 				}
       
   732 			break;
       
   733 			}
       
   734 		case EActive:
       
   735 			{
       
   736 			if (iCurrentStreamState == EPrimed) //Activate from Primed
       
   737 				{
       
   738 				// Reusing AudioCodec::Start for resuming
       
   739 				DP0(DLINFO,"==============  Stream is going from EPrimed -> ACTIVE");
       
   740 				err = iCodec->Start();
       
   741 				}
       
   742 			else if(iCurrentStreamState == EIdle) //Activate from Idle
       
   743 				{
       
   744 				DP0(DLINFO,"==============  Stream is going from EIdle -> ACTIVATE");
       
   745 				err = iCodec->Start();
       
   746 				}
       
   747 
       
   748 			if(err == KErrNone)
       
   749 				{
       
   750 				iCurrentStreamState = EActive;
       
   751 				}
       
   752 			break;
       
   753 			}
       
   754 		case EUninitialized:
       
   755 			{
       
   756 			err = DemolishDataPath();
       
   757 			if(err == KErrNone)
       
   758 				{
       
   759 				iCurrentStreamState = EUninitialized;
       
   760 				}
       
   761 			break;
       
   762 			}
       
   763 		case EDead:
       
   764 			{
       
   765 			err = DemolishDataPath();
       
   766 			if(err == KErrNone)
       
   767 				{
       
   768 				iCurrentStreamState = EDead;
       
   769 				}
       
   770 			break;
       
   771 			}
       
   772 		default:
       
   773 			err = KErrNotSupported;
       
   774 			DP1(DLINFO,"CAudioStream::ChangeState Unknown state! %d", iDesiredStreamState);
       
   775 			break;
       
   776 		}
       
   777 	DP0_RET(err, "%d");
       
   778 	}
       
   779 
       
   780 TInt CAudioStream::FlushBuffers()
       
   781 	{
       
   782 	DP_CONTEXT(CAudioStream::FlushBuffers *CD1*, CtxDevSound, DPLOCAL);
       
   783 	DP_IN();
       
   784 	
       
   785 	TInt err = KErrNone;
       
   786 
       
   787 	MOutputPort* outPort= static_cast<MOutputPort*>(iCodec);
       
   788 	if(outPort)
       
   789 		{
       
   790 		outPort->FlushBuffer(this);
       
   791 		}
       
   792 	else
       
   793 		{
       
   794 		err = KErrNotReady;
       
   795 		}
       
   796 	err = KErrNone;
       
   797 	DP0_RET(err, "%d");
       
   798 	}
       
   799 
       
   800 
       
   801 void CAudioStream::FlushComplete(TInt aError)
       
   802 	{
       
   803 	DP_CONTEXT(CAudioStream::FlushComplete *CD1*, CtxDevSound, DPLOCAL);
       
   804 	DP_IN();
       
   805 	TUint count = iAudioStreamObservers.Count();
       
   806 	for ( TUint i(0); i < count; i++ )
       
   807 		{
       
   808 		iAudioStreamObservers[i]->FlushComplete(aError);
       
   809 		}
       
   810 	DP_OUT();
       
   811 	}
       
   812 
       
   813 void CAudioStream::AllBuffersProcessed()
       
   814 	{
       
   815 	DP_CONTEXT(CAudioStream::AllBuffersProcessed *CD1*, CtxDevSound, DPLOCAL);
       
   816 	DP_IN();
       
   817 	TUint count = iAudioStreamObservers.Count();
       
   818 	for ( TUint i(0); i < count; i++ )
       
   819 		{
       
   820 		iAudioStreamObservers[i]->ProcessingFinished();
       
   821 		}
       
   822 	DP_OUT();
       
   823 	}
       
   824 
       
   825 void CAudioStream::ProcessingUnitError(TInt /*aError*/)
       
   826 	{
       
   827 	DP_CONTEXT(CAudioStream::ProcessingUnitError *CD1*, CtxDevSound, DPLOCAL);
       
   828 	DP_IN();
       
   829 	DP_OUT();
       
   830 	}
       
   831 
       
   832 // ---------------------------------------------------------------------------
       
   833 // CAudioStream::RegisterAudioCodecObserver
       
   834 // ---------------------------------------------------------------------------
       
   835 TInt CAudioStream::RegisterAudioCodecObserver(MAudioCodecObserver& aObserver)
       
   836 	{
       
   837 	DP_CONTEXT(CAudioStream::RegisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
       
   838 	DP_IN();
       
   839 	TInt err = iAudioCodecObservers.Find(&aObserver);
       
   840 	if(err == KErrNotFound)
       
   841 		{
       
   842 		err = iAudioCodecObservers.Append(&aObserver);
       
   843 		}
       
   844 	else
       
   845 		{
       
   846 		err = KErrAlreadyExists;
       
   847 		}
       
   848 	DP0_RET(err, "%d");
       
   849 	}
       
   850 
       
   851 // ---------------------------------------------------------------------------
       
   852 // CAudioStream::UnregisterAudioCodecObserver
       
   853 // ---------------------------------------------------------------------------
       
   854 void CAudioStream::UnregisterAudioCodecObserver(MAudioCodecObserver& aObserver)
       
   855 	{
       
   856 	DP_CONTEXT(CAudioStream::UnregisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
       
   857 	DP_IN();
       
   858 	TInt idxOrErr = iAudioCodecObservers.Find(&aObserver);
       
   859 	if( idxOrErr != KErrNotFound )
       
   860 		{
       
   861 		iAudioCodecObservers.Remove(idxOrErr);
       
   862 		}
       
   863 	DP_OUT();
       
   864 	}
       
   865 
       
   866 void CAudioStream::GetSupportedAModesComplete(TInt /*aError*/)
       
   867 	{
       
   868 	DP_CONTEXT(CAudioStream::GetSupportedAModesComplete *CD1*, CtxDevSound, DPLOCAL);
       
   869 	DP_IN();
       
   870 	DP_OUT();
       
   871 	}
       
   872 
       
   873 void CAudioStream::GetSupportedARatesComplete(TInt /*aError*/)
       
   874 	{
       
   875 	DP_CONTEXT(CAudioStream::GetSupportedARatesComplete *CD1*, CtxDevSound, DPLOCAL);
       
   876 	DP_IN();
       
   877 	DP_OUT();
       
   878 	}
       
   879 
       
   880 // ---------------------------------------------------------------------------
       
   881 // CAudioStream::GetSupportedSampleRates
       
   882 // ---------------------------------------------------------------------------
       
   883 TInt CAudioStream::GetSupportedSampleRates(RArray<TInt>& aSupportedRates)
       
   884 	{
       
   885 	TInt err = (KErrNotReady);
       
   886 	err = iCodec->SupportedRates(aSupportedRates);
       
   887 	return err;
       
   888 	}
       
   889 
       
   890 // ---------------------------------------------------------------------------
       
   891 // CAudioStream::GetSupportedModes
       
   892 // ---------------------------------------------------------------------------
       
   893 TInt CAudioStream::GetSupportedModes(RArray<TUid>& aSupportedModes)
       
   894 	{
       
   895 	TInt err = (KErrNotReady);
       
   896 	err = iCodec->SupportedModes(aSupportedModes);
       
   897 	return err;
       
   898 	}
       
   899 
       
   900 // end of file