os/mm/mmhais/refacladapt/src/audiostream/audiostream.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	// Ensure that there is no dereference of a NULL pointer
   659 	ASSERT(iDesiredStreamState < EInitialized || iDesiredStreamState > EActive || iCodec);
   660 	
   661 	switch (iDesiredStreamState)
   662 		{
   663 		case EInitialized:
   664 			{
   665 			if (iCurrentStreamState == EUninitialized) //Initialize
   666 				{
   667 				err = CreateDataPath();
   668 				if(err == KErrNone)
   669 					{
   670 					err = iCodec->Initialize();
   671 					}
   672 				}
   673 			else if( iCurrentStreamState == EIdle ) //codec unload (actually, unconfig)
   674 				{
   675 				iIsCodecConfig = EFalse;
   676 				err = KErrNone;
   677 				}
   678 			// Preemption 
   679 			// This A3F adaptation allows going from Active/Primed directly to initialised
   680 			// otherwise reference MMRC would need to handle those transitions separately 
   681 			else if(iCurrentStreamState == EActive || iCurrentStreamState == EPrimed) 
   682 				{
   683 				// To Idle 
   684 				err = iCodec->Stop();
   685 				// To Initilised
   686 				iIsCodecConfig = EFalse;
   687 				}
   688 				
   689 			if(err == KErrNone)
   690 				{
   691 				iCurrentStreamState = EInitialized;
   692 				}
   693 			break;
   694 			}
   695 		case EIdle:
   696 			{
   697 			if ( (iCurrentStreamState == EInitialized) && !iIsCodecConfig )
   698 				{
   699 				//codec loading actually configures sample rate and mode
   700 				err = iCodec->Load(iSampleRateConfig, iModeConfig);
   701 				iIsCodecConfig = (err == KErrNone);
   702 				}
   703 			else if (iCurrentStreamState == EActive)
   704 				{
   705 				err = iCodec->Stop();
   706 				}
   707 			else if (iCurrentStreamState == EPrimed)
   708 				{
   709 				err = iCodec->Stop();
   710 				}
   711 
   712 			if(err == KErrNone)
   713 				{
   714 				iTimeProcessed = 0;
   715 				iCurrentStreamState = EIdle;
   716 				}
   717 			break;
   718 			}
   719 		case EPrimed:
   720 			{
   721 			if (iCurrentStreamState == EIdle)
   722 				{
   723 				DP0(DLINFO,"==============  Stream is going from EIdle -> PRIMED");
   724 				DP0(DLINFO,"Nothing to be done");
   725 				}
   726 			else if (iCurrentStreamState == EActive)
   727 				{
   728 				DP0(DLINFO,"============== Stream is going from EActive -> PRIMED");
   729 				err = iCodec->Pause();
   730 				}
   731 			if(err == KErrNone)
   732 				{
   733 				iCurrentStreamState = EPrimed;
   734 				}
   735 			break;
   736 			}
   737 		case EActive:
   738 			{
   739 			if (iCurrentStreamState == EPrimed) //Activate from Primed
   740 				{
   741 				// Reusing AudioCodec::Start for resuming
   742 				DP0(DLINFO,"==============  Stream is going from EPrimed -> ACTIVE");
   743 				err = iCodec->Start();
   744 				}
   745 			else if(iCurrentStreamState == EIdle) //Activate from Idle
   746 				{
   747 				DP0(DLINFO,"==============  Stream is going from EIdle -> ACTIVATE");
   748 				err = iCodec->Start();
   749 				}
   750 
   751 			if(err == KErrNone)
   752 				{
   753 				iCurrentStreamState = EActive;
   754 				}
   755 			break;
   756 			}
   757 		case EUninitialized:
   758 			{
   759 			err = DemolishDataPath();
   760 			if(err == KErrNone)
   761 				{
   762 				iCurrentStreamState = EUninitialized;
   763 				}
   764 			break;
   765 			}
   766 		case EDead:
   767 			{
   768 			err = DemolishDataPath();
   769 			if(err == KErrNone)
   770 				{
   771 				iCurrentStreamState = EDead;
   772 				}
   773 			break;
   774 			}
   775 		default:
   776 			err = KErrNotSupported;
   777 			DP1(DLINFO,"CAudioStream::ChangeState Unknown state! %d", iDesiredStreamState);
   778 			break;
   779 		}
   780 	DP0_RET(err, "%d");
   781 	}
   782 
   783 TInt CAudioStream::FlushBuffers()
   784 	{
   785 	DP_CONTEXT(CAudioStream::FlushBuffers *CD1*, CtxDevSound, DPLOCAL);
   786 	DP_IN();
   787 	
   788 	TInt err = KErrNone;
   789 
   790 	MOutputPort* outPort= static_cast<MOutputPort*>(iCodec);
   791 	if(outPort)
   792 		{
   793 		outPort->FlushBuffer(this);
   794 		}
   795 	else
   796 		{
   797 		err = KErrNotReady;
   798 		}
   799 	err = KErrNone;
   800 	DP0_RET(err, "%d");
   801 	}
   802 
   803 
   804 void CAudioStream::FlushComplete(TInt aError)
   805 	{
   806 	DP_CONTEXT(CAudioStream::FlushComplete *CD1*, CtxDevSound, DPLOCAL);
   807 	DP_IN();
   808 	TUint count = iAudioStreamObservers.Count();
   809 	for ( TUint i(0); i < count; i++ )
   810 		{
   811 		iAudioStreamObservers[i]->FlushComplete(aError);
   812 		}
   813 	DP_OUT();
   814 	}
   815 
   816 void CAudioStream::AllBuffersProcessed()
   817 	{
   818 	DP_CONTEXT(CAudioStream::AllBuffersProcessed *CD1*, CtxDevSound, DPLOCAL);
   819 	DP_IN();
   820 	TUint count = iAudioStreamObservers.Count();
   821 	for ( TUint i(0); i < count; i++ )
   822 		{
   823 		iAudioStreamObservers[i]->ProcessingFinished();
   824 		}
   825 	DP_OUT();
   826 	}
   827 
   828 void CAudioStream::ProcessingUnitError(TInt /*aError*/)
   829 	{
   830 	DP_CONTEXT(CAudioStream::ProcessingUnitError *CD1*, CtxDevSound, DPLOCAL);
   831 	DP_IN();
   832 	DP_OUT();
   833 	}
   834 
   835 // ---------------------------------------------------------------------------
   836 // CAudioStream::RegisterAudioCodecObserver
   837 // ---------------------------------------------------------------------------
   838 TInt CAudioStream::RegisterAudioCodecObserver(MAudioCodecObserver& aObserver)
   839 	{
   840 	DP_CONTEXT(CAudioStream::RegisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
   841 	DP_IN();
   842 	TInt err = iAudioCodecObservers.Find(&aObserver);
   843 	if(err == KErrNotFound)
   844 		{
   845 		err = iAudioCodecObservers.Append(&aObserver);
   846 		}
   847 	else
   848 		{
   849 		err = KErrAlreadyExists;
   850 		}
   851 	DP0_RET(err, "%d");
   852 	}
   853 
   854 // ---------------------------------------------------------------------------
   855 // CAudioStream::UnregisterAudioCodecObserver
   856 // ---------------------------------------------------------------------------
   857 void CAudioStream::UnregisterAudioCodecObserver(MAudioCodecObserver& aObserver)
   858 	{
   859 	DP_CONTEXT(CAudioStream::UnregisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
   860 	DP_IN();
   861 	TInt idxOrErr = iAudioCodecObservers.Find(&aObserver);
   862 	if( idxOrErr != KErrNotFound )
   863 		{
   864 		iAudioCodecObservers.Remove(idxOrErr);
   865 		}
   866 	DP_OUT();
   867 	}
   868 
   869 void CAudioStream::GetSupportedAModesComplete(TInt /*aError*/)
   870 	{
   871 	DP_CONTEXT(CAudioStream::GetSupportedAModesComplete *CD1*, CtxDevSound, DPLOCAL);
   872 	DP_IN();
   873 	DP_OUT();
   874 	}
   875 
   876 void CAudioStream::GetSupportedARatesComplete(TInt /*aError*/)
   877 	{
   878 	DP_CONTEXT(CAudioStream::GetSupportedARatesComplete *CD1*, CtxDevSound, DPLOCAL);
   879 	DP_IN();
   880 	DP_OUT();
   881 	}
   882 
   883 // ---------------------------------------------------------------------------
   884 // CAudioStream::GetSupportedSampleRates
   885 // ---------------------------------------------------------------------------
   886 TInt CAudioStream::GetSupportedSampleRates(RArray<TInt>& aSupportedRates)
   887 	{
   888 	TInt err = (KErrNotReady);
   889 	err = iCodec->SupportedRates(aSupportedRates);
   890 	return err;
   891 	}
   892 
   893 // ---------------------------------------------------------------------------
   894 // CAudioStream::GetSupportedModes
   895 // ---------------------------------------------------------------------------
   896 TInt CAudioStream::GetSupportedModes(RArray<TUid>& aSupportedModes)
   897 	{
   898 	TInt err = (KErrNotReady);
   899 	err = iCodec->SupportedModes(aSupportedModes);
   900 	return err;
   901 	}
   902 
   903 // end of file