1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmhais/refacladapt/src/audiostream/audiostream.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,903 @@
1.4 +//audiostream.cpp
1.5 +
1.6 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.7 +// All rights reserved.
1.8 +// This component and the accompanying materials are made available
1.9 +// under the terms of "Eclipse Public License v1.0"
1.10 +// which accompanies this distribution, and is available
1.11 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.12 +//
1.13 +// Initial Contributors:
1.14 +// Nokia Corporation - initial contribution.
1.15 +//
1.16 +// Contributors:
1.17 +//
1.18 +// Description:
1.19 +//
1.20 +
1.21 +
1.22 +
1.23 +
1.24 +#include <a3f/a3fbase.h>
1.25 +#include <a3f/audioprocessingunittypeuids.h>
1.26 +#include <a3f/a3ffourcclookup.h>
1.27 +
1.28 +#include "audiostream.h"
1.29 +
1.30 +// PHYSICAL COMPONENTS
1.31 +#include "audiocodec.h"
1.32 +#include "audiostream.h"
1.33 +#include "buffersource.h"
1.34 +#include "buffersink.h"
1.35 +#include "audiodevicesource.h"
1.36 +#include "audiodevicesink.h"
1.37 +#include "audiogaincontrol.h"
1.38 +#include "maudiostreamadaptationobserver.h"
1.39 +
1.40 +#include <a3f/maudiodatasupplier.h>
1.41 +#include <a3f/maudiodataconsumer.h>
1.42 +
1.43 +#include "minputport.h"
1.44 +#include "moutputport.h"
1.45 +#include "audiocontext.h"
1.46 +
1.47 +#include <ecom/implementationproxy.h>
1.48 +
1.49 +
1.50 +
1.51 +const TInt KSampleRate8000Hz = 8000;
1.52 +
1.53 +// Map the interface implementation UIDs to implementation factory functions
1.54 +const TImplementationProxy ImplementationTable[] =
1.55 + {
1.56 + IMPLEMENTATION_PROXY_ENTRY(0x10283461, CAudioStream::NewL),
1.57 + };
1.58 +
1.59 +
1.60 +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
1.61 + {
1.62 + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
1.63 + return ImplementationTable;
1.64 + }
1.65 +
1.66 +// ---------------------------------------------------------------------------
1.67 +// Constructor
1.68 +// ---------------------------------------------------------------------------
1.69 +//
1.70 +CAudioStream::CAudioStream()
1.71 + : iCurrentStreamState(EUninitialized),
1.72 + iDesiredStreamState(EUninitialized)
1.73 + {
1.74 + TRACE_CREATE();
1.75 + DP_CONTEXT(CAudioStream::CAudioStream *CD1*, CtxDevSound, DPLOCAL);
1.76 + DP_IN();
1.77 + // Some init config values
1.78 + iSampleRateConfig = KSampleRate8000Hz;
1.79 + iModeConfig = KA3FModeMono;
1.80 +
1.81 + DP_OUT();
1.82 + }
1.83 +
1.84 +// ---------------------------------------------------------------------------
1.85 +// Factory method
1.86 +// ---------------------------------------------------------------------------
1.87 +//
1.88 +CAudioStream* CAudioStream::NewL()
1.89 + {
1.90 + DP_STATIC_CONTEXT(CAudioStream::NewL *CD0*, CtxDevSound, DPLOCAL);
1.91 + DP_IN();
1.92 + CAudioStream* self = new(ELeave)CAudioStream();
1.93 + CleanupStack::PushL(self);
1.94 + self->ConstructL();
1.95 + CleanupStack::Pop(self);
1.96 + DP0_RET(self, "0x%x");
1.97 + }
1.98 +
1.99 +// ---------------------------------------------------------------------------
1.100 +// Second phase constructor
1.101 +// ---------------------------------------------------------------------------
1.102 +//
1.103 +void CAudioStream::ConstructL()
1.104 + {
1.105 + DP_CONTEXT(CAudioStream::ConstructL *CD1*, CtxDevSound, DPLOCAL);
1.106 + DP_IN();
1.107 + DP_OUT();
1.108 + }
1.109 +
1.110 +// ---------------------------------------------------------------------------
1.111 +// Destructor
1.112 +// ---------------------------------------------------------------------------
1.113 +//
1.114 +CAudioStream::~CAudioStream()
1.115 + {
1.116 + DP_CONTEXT(CAudioStream::~CAudioStream *CD1*, CtxDevSound, DPLOCAL);
1.117 + DP_IN();
1.118 +
1.119 + iAudioStreamObservers.Close();
1.120 + iAudioCodecObservers.Close();
1.121 + // Just for now
1.122 + DeletePhysicalComponents();
1.123 + REComSession::FinalClose();
1.124 + DP_OUT();
1.125 + }
1.126 +
1.127 +// ---------------------------------------------------------------------------
1.128 +// CAudioStream::RegisterAudioStreamObserver
1.129 +// ---------------------------------------------------------------------------
1.130 +//
1.131 +TInt CAudioStream::RegisterAudioStreamObserver(MAudioStreamAdaptationObserver& aObserver)
1.132 + {
1.133 + DP_CONTEXT(CAudioStream::RegisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL);
1.134 + DP_IN();
1.135 + TInt err = iAudioStreamObservers.Find(&aObserver);
1.136 + if(err == KErrNotFound)
1.137 + {
1.138 + err = iAudioStreamObservers.Append(&aObserver);
1.139 + }
1.140 + else
1.141 + {
1.142 + err = KErrAlreadyExists;
1.143 + }
1.144 + DP0_RET(err, "%d");
1.145 + }
1.146 +
1.147 +// ---------------------------------------------------------------------------
1.148 +// CAudioStream::UnregisterAudioStreamObserver
1.149 +// ---------------------------------------------------------------------------
1.150 +//
1.151 +void CAudioStream::UnregisterAudioStreamObserver(MAudioStreamAdaptationObserver& aObserver)
1.152 + {
1.153 + DP_CONTEXT(CAudioStream::UnregisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL);
1.154 + DP_IN();
1.155 + TInt idxOrErr = iAudioStreamObservers.Find(&aObserver);
1.156 + if( idxOrErr != KErrNotFound )
1.157 + {
1.158 + iAudioStreamObservers.Remove(idxOrErr);
1.159 + }
1.160 + DP_OUT();
1.161 + }
1.162 +
1.163 +
1.164 +// ---------------------------------------------------------------------------
1.165 +// CAudioStream::SetFourCC
1.166 +// ---------------------------------------------------------------------------
1.167 +//
1.168 +void CAudioStream::SetFourCC(const CFourCCConvertor& aFourCCConvertor)
1.169 + {
1.170 + DP_CONTEXT(CAudioStream::SetFourCC *CD1*, CtxDevSound, DPLOCAL);
1.171 + DP_IN();
1.172 + CFourCCConvertor& ref = const_cast<CFourCCConvertor&>(aFourCCConvertor);
1.173 + iFourCCConvertor = static_cast<CFourCCConvertor*>(static_cast<TAny*>(&ref));
1.174 + DP_OUT();
1.175 + }
1.176 +
1.177 +
1.178 +// ---------------------------------------------------------------------------
1.179 +// CAudioStream::UnregisterAudioStreamObserver
1.180 +// ---------------------------------------------------------------------------
1.181 +//
1.182 +void CAudioStream::UnregisterAllAudioStreamObserver()
1.183 + {
1.184 + DP_CONTEXT(CAudioStream::UnregisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL);
1.185 + DP_IN();
1.186 +
1.187 + iAudioStreamObservers.Reset();
1.188 +
1.189 + DP_OUT();
1.190 + }
1.191 +
1.192 +
1.193 +// ---------------------------------------------------------------------------
1.194 +// MMRC extension mechanism
1.195 +// ---------------------------------------------------------------------------
1.196 +TAny* CAudioStream::GetComponent(TUid aType)
1.197 + {
1.198 + TAny* ptr = NULL;
1.199 + MLogicalChain* clientDesiredChain = NULL;
1.200 + CAudioContext* context = static_cast<CAudioContext*>(iAudioContext);
1.201 + if(context)
1.202 + {
1.203 + clientDesiredChain = context->GetLogicalChain(0);
1.204 + }
1.205 + if (clientDesiredChain)
1.206 + {
1.207 + ptr = clientDesiredChain->GetComponent(aType);
1.208 + }
1.209 + return ptr;
1.210 + }
1.211 +
1.212 +// ---------------------------------------------------------------------------
1.213 +// CAudioStream::Message
1.214 +// ---------------------------------------------------------------------------
1.215 +TInt CAudioStream::Message(MLogicalChain& aCurrentChain, MLogicalChain& aDesiredChain, MAudioContext& aContext, TInt aFlags)
1.216 + {
1.217 + DP_CONTEXT(CAudioStream::Message *CD0*, CtxDevSound, DPLOCAL);
1.218 + DP_IN();
1.219 + TInt err = KErrNone;
1.220 +
1.221 + iCurrentChain = &aCurrentChain;
1.222 + iDesiredChain = &aDesiredChain;
1.223 +
1.224 + TUint messageType = aDesiredChain.MessageType();
1.225 +
1.226 + iAudioContext = &aContext;
1.227 +
1.228 + CAudioContext* audioContext = static_cast<CAudioContext*> (iAudioContext);
1.229 + // TO NOTIFY DIRECTLY CONTEXT
1.230 + MMultimediaResourceControlObserver* mmrcObserver = static_cast<MMultimediaResourceControlObserver*>(audioContext);
1.231 +
1.232 + // Register stream observer
1.233 + if (messageType & ERegisterStreamObserver != 0)
1.234 + {
1.235 + // Use MMRC extension mechanism
1.236 + TAny* ptr = GetComponent(KUidAudioStreamAdaptationObserver);
1.237 + MAudioStreamAdaptationObserver* observer = static_cast<MAudioStreamAdaptationObserver*>(ptr);
1.238 + if(observer)
1.239 + {
1.240 + err = RegisterAudioStreamObserver(*observer);
1.241 + }
1.242 + }
1.243 +
1.244 + // Register codec observer
1.245 + if (messageType & ERegisterCodecObserver != 0)
1.246 + {
1.247 + // Use MMRC extension mechanism
1.248 + TAny* ptr = GetComponent(KUidAudioCodecObserver);
1.249 + MAudioCodecObserver* observer = static_cast<MAudioCodecObserver*>(ptr);
1.250 + if (observer)
1.251 + {
1.252 + err = RegisterAudioCodecObserver(*observer);
1.253 + }
1.254 + }
1.255 +
1.256 + // Component creation
1.257 + TUint bit = messageType & EComponentCreation;
1.258 + if( (err == KErrNone) && (bit != 0) )
1.259 + {
1.260 + CAudioContext* context = static_cast<CAudioContext*>(iAudioContext);
1.261 + MLogicalChain* clientDesiredChain = context->GetLogicalChain(0);
1.262 + err = CreatePhysicalComponents(*clientDesiredChain);
1.263 +
1.264 + // For Configuration
1.265 + if (err==KErrNone)
1.266 + {
1.267 + clientDesiredChain->SetAdaptationStream(*this);
1.268 + clientDesiredChain->SetStreamBufferControl(*this);
1.269 + }
1.270 + }
1.271 +
1.272 + // Component alteration
1.273 + // Changes that must be applied before stream state transition
1.274 + TBool configCodec = EFalse;
1.275 + bit = messageType & EComponentAlterationCodec;
1.276 + if( (err == KErrNone) && (bit != 0) )
1.277 + {
1.278 + // Set Format
1.279 + if(iCodec)
1.280 + {
1.281 + TUid desiredCodecFormat = iDesiredChain->CodecFormat();
1.282 + err = iCodec->SetFormat( desiredCodecFormat );
1.283 + }
1.284 +
1.285 + if(err == KErrNone)
1.286 + {
1.287 + //if samplerate or mode has changed, update value and trigger callbacks at appropriate point
1.288 + if ((iDesiredChain->GetSampleRate() > 0) && (iDesiredChain->GetSampleRate() != iSampleRateConfig))
1.289 + {
1.290 + iSampleRateConfig = iDesiredChain->GetSampleRate();
1.291 + configCodec = ETrue;
1.292 + }
1.293 + if ((iDesiredChain->GetMode() != KNullUid) && (iDesiredChain->GetMode() != iModeConfig))
1.294 + {
1.295 + iModeConfig = iDesiredChain->GetMode();
1.296 + configCodec = ETrue;
1.297 + }
1.298 + }
1.299 + }
1.300 +
1.301 +
1.302 + bit = messageType & EComponentAlterationGain;
1.303 + if( (err == KErrNone) && (bit != 0) )
1.304 + {
1.305 + // Apply volume ramp
1.306 + // Note that ramp operation and gain now are applied separately because current tone arquitecture
1.307 + // need the volume ramp to be set before start the tonehwdevice
1.308 + TTimeIntervalMicroSeconds currentRampTimeValue = 0;
1.309 + TUid currentRampTimeOperation(KNullUid);
1.310 + TTimeIntervalMicroSeconds desiredRampTimeValue = 0;
1.311 + TUid desiredRampTimeOperation(KNullUid);
1.312 + iCurrentChain->GetVolumeRampParameters(currentRampTimeOperation, currentRampTimeValue);
1.313 + iDesiredChain->GetVolumeRampParameters(desiredRampTimeOperation, desiredRampTimeValue);
1.314 +
1.315 + if(currentRampTimeOperation != desiredRampTimeOperation ||
1.316 + currentRampTimeValue.Int64() != desiredRampTimeValue.Int64() )
1.317 + {
1.318 + if (iGainControl)
1.319 + {
1.320 + err = iGainControl->ConfigureRamp(desiredRampTimeOperation, desiredRampTimeValue);
1.321 + }
1.322 + }
1.323 + }
1.324 +
1.325 + //Configuration request
1.326 + // Stream state
1.327 + TBool invokeStateEventCallback = EFalse;
1.328 + iDesiredStreamState = iDesiredChain->StreamState();
1.329 + if( (err == KErrNone) && (iCurrentStreamState != iDesiredStreamState) )
1.330 + {
1.331 + err = ChangeState(iCurrentStreamState, iDesiredStreamState);
1.332 + if (err == KErrNone)
1.333 + {
1.334 + iCurrentStreamState = iDesiredStreamState;
1.335 + }
1.336 + invokeStateEventCallback = ETrue;
1.337 + }
1.338 +
1.339 + // Component alteration
1.340 + // Changes that must be applied after stream state transition
1.341 + TBool gainUpdated = EFalse;
1.342 + bit = messageType & EComponentAlterationGain;
1.343 + if( (err == KErrNone) && (bit != 0) )
1.344 + {
1.345 + TAny* ptr = GetComponent(KUidAudioGainControl);
1.346 + MAudioGainControl* gaincontrol = static_cast<MAudioGainControl*>(ptr);
1.347 + if (iGainControl && gaincontrol)
1.348 + {
1.349 + RArray<TAudioChannelGain> channels;
1.350 + TInt err = gaincontrol->GetGain(channels);
1.351 + if (channels.Count() != 0 )
1.352 + {
1.353 + err = iGainControl->SetGain(channels);
1.354 + gainUpdated = ETrue;
1.355 + }
1.356 + channels.Close();
1.357 + }
1.358 + }
1.359 +
1.360 + TBool invokeCodecCallbacks = EFalse;
1.361 + bit = messageType & EComponentAlterationCodec;
1.362 + if ( (err == KErrNone) && (bit != 0) && configCodec && (iCurrentStreamState == EInitialized) )
1.363 + {
1.364 + //codec loading actually configures sample rate and mode
1.365 + ASSERT(iCodec);
1.366 + err = iCodec->Load(iSampleRateConfig, iModeConfig);
1.367 + iIsCodecConfig = (err == KErrNone);
1.368 + invokeCodecCallbacks = ETrue;
1.369 + if ( err != KErrNone )
1.370 + {
1.371 + //get back to previous values in case of error
1.372 + iSampleRateConfig = iCurrentChain->GetSampleRate();
1.373 + iModeConfig = iCurrentChain->GetMode();
1.374 + }
1.375 + }
1.376 +
1.377 + // Component destruction
1.378 + bit = messageType & EComponentDestruction;
1.379 + if( (err == KErrNone) && (bit != 0) )
1.380 + {
1.381 + DeletePhysicalComponents();
1.382 + }
1.383 +
1.384 + TUint isStopping = aFlags & KServerStopping;
1.385 + TUint preemptionRequest = aFlags & KPreemptionRequest;
1.386 +
1.387 + // HERE WE CAN GUARANTEE THAT THE REQUEST IS SUCCESFUL
1.388 + // Notify context
1.389 + // 1ST CALLBACK
1.390 + if(!preemptionRequest)
1.391 + {
1.392 + mmrcObserver->ReceiveResourceUpdate(&aDesiredChain, KErrNone);
1.393 + }
1.394 + else
1.395 + {
1.396 + mmrcObserver->ReceivePreemptionUpdate(&aDesiredChain, err);
1.397 + }
1.398 +
1.399 + // Processing unit callbacks
1.400 + // Gain control
1.401 + // Note that due to error checking before applying any change
1.402 + // this callback always returned the error obtained by calling SetGain
1.403 + // or KErrNone
1.404 + if(gainUpdated)
1.405 + {
1.406 + if (iGainControl)
1.407 + {
1.408 + iGainControl->IssueGainChangedCallBack(err);
1.409 + }
1.410 + }
1.411 +
1.412 + // Stream
1.413 + if(invokeStateEventCallback)
1.414 + {
1.415 + invokeStateEventCallback = EFalse;
1.416 + for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ )
1.417 + {
1.418 + if ( !isStopping )
1.419 + {
1.420 + iAudioStreamObservers[idx]->StateEvent(err, iCurrentStreamState);
1.421 + }
1.422 + }
1.423 + }
1.424 + if( invokeCodecCallbacks && (iCurrentStreamState == EInitialized) )
1.425 + {
1.426 + TInt count = iAudioCodecObservers.Count();
1.427 + for ( TInt idx = 0; idx < count; idx++ )
1.428 + {
1.429 + //TODO replace this functionality with the new mmrc
1.430 + iAudioCodecObservers[idx]->SampleRateSet(err);
1.431 + iAudioCodecObservers[idx]->ModeSet(err);
1.432 + }
1.433 + }
1.434 +
1.435 + // Now has no effect on context
1.436 + // But it's needed to let the MMRC know about the operation being completed
1.437 + // and in such way let it to know that
1.438 + for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ )
1.439 + {
1.440 + if ( !isStopping )
1.441 + {
1.442 + iAudioStreamObservers[idx]->PhysicalAdaptationEvent(EOperationComplete, err);
1.443 + }
1.444 + }
1.445 +
1.446 + // Don't need to send last callback sync
1.447 + // Let MMRC do it
1.448 +
1.449 + DP0_RET(err, "%d");
1.450 + }
1.451 +
1.452 +// ---------------------------------------------------------------------------
1.453 +// CAudioStream::DeletePhysicalComponents
1.454 +// ---------------------------------------------------------------------------
1.455 +void CAudioStream::DeletePhysicalComponents()
1.456 + {
1.457 + DP_CONTEXT(CAudioStream::DeletePhysicalComponents *CD0*, CtxDevSound, DPLOCAL);
1.458 + DP_IN();
1.459 + if(iBufferSource)
1.460 + {
1.461 + delete iBufferSource;
1.462 + iBufferSource = NULL;
1.463 + }
1.464 + if(iBufferSink)
1.465 + {
1.466 + delete iBufferSink;
1.467 + iBufferSink = NULL;
1.468 + }
1.469 + if(iCodec)
1.470 + {
1.471 + delete iCodec;
1.472 + iCodec = NULL;
1.473 + iIsCodecConfig = EFalse;
1.474 + }
1.475 + if(iGainControl)
1.476 + {
1.477 + delete iGainControl;
1.478 + iGainControl = NULL;
1.479 + }
1.480 + if(iDeviceSource)
1.481 + {
1.482 + delete iDeviceSource;
1.483 + iDeviceSource = NULL;
1.484 + }
1.485 + if(iDeviceSink)
1.486 + {
1.487 + delete iDeviceSink;
1.488 + iDeviceSink= NULL;
1.489 + }
1.490 + DP_OUT();
1.491 + }
1.492 +
1.493 +
1.494 +// ---------------------------------------------------------------------------
1.495 +// CAudioStream::CreatePhysicalComponents
1.496 +// ---------------------------------------------------------------------------
1.497 +TInt CAudioStream::CreatePhysicalComponents(MLogicalChain& aDesiredChain)
1.498 + {
1.499 + DP_CONTEXT(CAudioStream::CreatePhysicalComponents *CD0*, CtxDevSound, DPLOCAL);
1.500 + DP_IN();
1.501 +
1.502 + TInt err = KErrNone;
1.503 + TInt units = aDesiredChain.AudioProcessingUnitsCount();
1.504 + TInt index=0;
1.505 + TUid typeId;
1.506 +
1.507 + for (index=0; index < units ; index++)
1.508 + {
1.509 + typeId = aDesiredChain.AudioProcessingUnitUid(index);
1.510 +
1.511 + // By the moment all components
1.512 + if (err == KErrNone)
1.513 + {
1.514 + if (typeId == KUidAudioDecoder || typeId == KUidAudioEncoder )
1.515 + {
1.516 + if(!iCodec)
1.517 + {
1.518 + TRAP(err, iCodec = CAudioCodec::NewL(typeId, *iFourCCConvertor ));
1.519 + iIsCodecConfig = EFalse;
1.520 + iCodec->RegisterAudioCodecObserver(*this);
1.521 + TAny* ptr = GetComponent(KUidAudioCodecAdaptationObserver);
1.522 + MAudioCodecAdaptationObserver* observer = static_cast<MAudioCodecAdaptationObserver*>(ptr);
1.523 + if(observer)
1.524 + {
1.525 + iCodec->RegisterAudioCodecObserver(*observer);
1.526 + }
1.527 + // For HW custom interface
1.528 + aDesiredChain.SetCustomInterfaceProvider(*iCodec);
1.529 + }
1.530 + if(iGainControl)
1.531 + {
1.532 + iGainControl->SetHelper(*iCodec);
1.533 + }
1.534 + // This mechanism is temporary and must be replaced
1.535 + // with the Extension mechanism when the MMRC server
1.536 + aDesiredChain.SetStreamPositionControl(*iCodec);
1.537 + }
1.538 + else if (typeId == KUidMmfBufferSource)
1.539 + {
1.540 + if(!iBufferSource)
1.541 + {
1.542 + TRAP(err,iBufferSource = CBufferSource::NewL());
1.543 + // This mechanism is temporary and must be replaced
1.544 + // with the Extension mechanism when the MMRC server
1.545 + aDesiredChain.SetAdaptationSource(*iBufferSource);
1.546 + /*
1.547 + TAny* ptr = aDesiredChain.GetComponent(KUidMmfBufferSource);
1.548 + MMMFAudioDataSupplier* supplier = static_cast<MMMFAudioDataSupplier*>(ptr);
1.549 + if(supplier)
1.550 + {
1.551 + iBufferSource->SetDataSupplier(*supplier);
1.552 + }
1.553 + */
1.554 + }
1.555 + }
1.556 + else if (typeId == KUidMmfBufferSink)
1.557 + {
1.558 + if(!iBufferSink)
1.559 + {
1.560 + TRAP(err, iBufferSink = CBufferSink::NewL());
1.561 + // This mechanism is temporary and must be replaced
1.562 + // with the Extension mechanism when the MMRC server
1.563 + aDesiredChain.SetAdaptationSink(*iBufferSink);
1.564 + }
1.565 + }
1.566 + else if (typeId == KUidAudioGainControl)
1.567 + {
1.568 + if(!iGainControl)
1.569 + {
1.570 + // This mechanism is temporary and must be replaced
1.571 + // with the Extension mechanism when the MMRC server
1.572 + TRAP(err, iGainControl = CAudioGainControl::NewL());
1.573 + aDesiredChain.SetAdaptationGainControl(*iGainControl);
1.574 + }
1.575 + }
1.576 + else if (typeId == KUidAudioDeviceSink)
1.577 + {
1.578 + if(!iDeviceSink)
1.579 + {
1.580 + TRAP(err, iDeviceSink = CAudioDeviceSink::NewL());
1.581 + }
1.582 + }
1.583 + else if (typeId == KUidAudioDeviceSource)
1.584 + {
1.585 + if(!iDeviceSource)
1.586 + {
1.587 + TRAP(err, iDeviceSource = CAudioDeviceSource::NewL());
1.588 + }
1.589 + }
1.590 + else
1.591 + {
1.592 + err = KErrNotSupported;
1.593 + }
1.594 + }
1.595 +
1.596 + // Notify the observers
1.597 + for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ )
1.598 + {
1.599 + iAudioStreamObservers[idx]->AddProcessingUnitComplete(typeId, err);
1.600 + }
1.601 + }
1.602 + DP0_RET(err, "%d");
1.603 + }
1.604 +
1.605 +// ---------------------------------------------------------------------------
1.606 +// CAudioStream::CreateDataPath
1.607 +// ---------------------------------------------------------------------------
1.608 +TInt CAudioStream::CreateDataPath()
1.609 + {
1.610 + DP_CONTEXT(CAudioStream::CreateDataPath *CD1*, CtxDevSound, DPLOCAL);
1.611 + DP_IN();
1.612 + TInt err(KErrNotReady);
1.613 +
1.614 + if(iBufferSource && iCodec) // && iSink && iGain)
1.615 + {
1.616 + // TMode == Decode
1.617 + if(KErrNone == iBufferSource->GetOutputPort(iOutputport) && KErrNone == iCodec->GetInputPort(iInputport))
1.618 + {
1.619 + iOutputport->SetInput(iInputport);
1.620 + iInputport->SetOutput(iOutputport);
1.621 + err = KErrNone;
1.622 + }
1.623 + }
1.624 + else if(iBufferSink && iCodec) // && iSink && iGain)
1.625 + {
1.626 + //TMode == Encode
1.627 + if(KErrNone == iCodec->GetOutputPort(iOutputport) && KErrNone == iBufferSink->GetInputPort(iInputport))
1.628 + {
1.629 + iOutputport->SetInput(iInputport);
1.630 + iInputport->SetOutput(iOutputport);
1.631 + err = KErrNone;
1.632 + }
1.633 + }
1.634 + DP0_RET(err, "%d");
1.635 + }
1.636 +
1.637 +// ---------------------------------------------------------------------------
1.638 +// CAudioStream::DemolishDataPath
1.639 +// ---------------------------------------------------------------------------
1.640 +//
1.641 +TInt CAudioStream::DemolishDataPath()
1.642 + {
1.643 + DP_CONTEXT(CAudioStream::DemolishDataPath *CD1*, CtxDevSound, DPLOCAL);
1.644 + DP_IN();
1.645 + iOutputport->RemoveInput(iInputport);
1.646 + iInputport->RemoveOutput(iOutputport);
1.647 + DP0_RET(KErrNone, "%d");
1.648 + }
1.649 +
1.650 +// ---------------------------------------------------------------------------
1.651 +// CAudioStream::ChangeState
1.652 +// ---------------------------------------------------------------------------
1.653 +TInt CAudioStream::ChangeState(TAudioState aPreviousState, TAudioState aDesiredState)
1.654 + {
1.655 + DP_CONTEXT(CAudioStream::ChangeState *CD1*, CtxDevSound, DPLOCAL);
1.656 + DP_IN();
1.657 + TInt err(KErrNone);
1.658 + iCurrentStreamState = aPreviousState;
1.659 + iDesiredStreamState = aDesiredState;
1.660 +
1.661 + // Ensure that there is no dereference of a NULL pointer
1.662 + ASSERT(iDesiredStreamState < EInitialized || iDesiredStreamState > EActive || iCodec);
1.663 +
1.664 + switch (iDesiredStreamState)
1.665 + {
1.666 + case EInitialized:
1.667 + {
1.668 + if (iCurrentStreamState == EUninitialized) //Initialize
1.669 + {
1.670 + err = CreateDataPath();
1.671 + if(err == KErrNone)
1.672 + {
1.673 + err = iCodec->Initialize();
1.674 + }
1.675 + }
1.676 + else if( iCurrentStreamState == EIdle ) //codec unload (actually, unconfig)
1.677 + {
1.678 + iIsCodecConfig = EFalse;
1.679 + err = KErrNone;
1.680 + }
1.681 + // Preemption
1.682 + // This A3F adaptation allows going from Active/Primed directly to initialised
1.683 + // otherwise reference MMRC would need to handle those transitions separately
1.684 + else if(iCurrentStreamState == EActive || iCurrentStreamState == EPrimed)
1.685 + {
1.686 + // To Idle
1.687 + err = iCodec->Stop();
1.688 + // To Initilised
1.689 + iIsCodecConfig = EFalse;
1.690 + }
1.691 +
1.692 + if(err == KErrNone)
1.693 + {
1.694 + iCurrentStreamState = EInitialized;
1.695 + }
1.696 + break;
1.697 + }
1.698 + case EIdle:
1.699 + {
1.700 + if ( (iCurrentStreamState == EInitialized) && !iIsCodecConfig )
1.701 + {
1.702 + //codec loading actually configures sample rate and mode
1.703 + err = iCodec->Load(iSampleRateConfig, iModeConfig);
1.704 + iIsCodecConfig = (err == KErrNone);
1.705 + }
1.706 + else if (iCurrentStreamState == EActive)
1.707 + {
1.708 + err = iCodec->Stop();
1.709 + }
1.710 + else if (iCurrentStreamState == EPrimed)
1.711 + {
1.712 + err = iCodec->Stop();
1.713 + }
1.714 +
1.715 + if(err == KErrNone)
1.716 + {
1.717 + iTimeProcessed = 0;
1.718 + iCurrentStreamState = EIdle;
1.719 + }
1.720 + break;
1.721 + }
1.722 + case EPrimed:
1.723 + {
1.724 + if (iCurrentStreamState == EIdle)
1.725 + {
1.726 + DP0(DLINFO,"============== Stream is going from EIdle -> PRIMED");
1.727 + DP0(DLINFO,"Nothing to be done");
1.728 + }
1.729 + else if (iCurrentStreamState == EActive)
1.730 + {
1.731 + DP0(DLINFO,"============== Stream is going from EActive -> PRIMED");
1.732 + err = iCodec->Pause();
1.733 + }
1.734 + if(err == KErrNone)
1.735 + {
1.736 + iCurrentStreamState = EPrimed;
1.737 + }
1.738 + break;
1.739 + }
1.740 + case EActive:
1.741 + {
1.742 + if (iCurrentStreamState == EPrimed) //Activate from Primed
1.743 + {
1.744 + // Reusing AudioCodec::Start for resuming
1.745 + DP0(DLINFO,"============== Stream is going from EPrimed -> ACTIVE");
1.746 + err = iCodec->Start();
1.747 + }
1.748 + else if(iCurrentStreamState == EIdle) //Activate from Idle
1.749 + {
1.750 + DP0(DLINFO,"============== Stream is going from EIdle -> ACTIVATE");
1.751 + err = iCodec->Start();
1.752 + }
1.753 +
1.754 + if(err == KErrNone)
1.755 + {
1.756 + iCurrentStreamState = EActive;
1.757 + }
1.758 + break;
1.759 + }
1.760 + case EUninitialized:
1.761 + {
1.762 + err = DemolishDataPath();
1.763 + if(err == KErrNone)
1.764 + {
1.765 + iCurrentStreamState = EUninitialized;
1.766 + }
1.767 + break;
1.768 + }
1.769 + case EDead:
1.770 + {
1.771 + err = DemolishDataPath();
1.772 + if(err == KErrNone)
1.773 + {
1.774 + iCurrentStreamState = EDead;
1.775 + }
1.776 + break;
1.777 + }
1.778 + default:
1.779 + err = KErrNotSupported;
1.780 + DP1(DLINFO,"CAudioStream::ChangeState Unknown state! %d", iDesiredStreamState);
1.781 + break;
1.782 + }
1.783 + DP0_RET(err, "%d");
1.784 + }
1.785 +
1.786 +TInt CAudioStream::FlushBuffers()
1.787 + {
1.788 + DP_CONTEXT(CAudioStream::FlushBuffers *CD1*, CtxDevSound, DPLOCAL);
1.789 + DP_IN();
1.790 +
1.791 + TInt err = KErrNone;
1.792 +
1.793 + MOutputPort* outPort= static_cast<MOutputPort*>(iCodec);
1.794 + if(outPort)
1.795 + {
1.796 + outPort->FlushBuffer(this);
1.797 + }
1.798 + else
1.799 + {
1.800 + err = KErrNotReady;
1.801 + }
1.802 + err = KErrNone;
1.803 + DP0_RET(err, "%d");
1.804 + }
1.805 +
1.806 +
1.807 +void CAudioStream::FlushComplete(TInt aError)
1.808 + {
1.809 + DP_CONTEXT(CAudioStream::FlushComplete *CD1*, CtxDevSound, DPLOCAL);
1.810 + DP_IN();
1.811 + TUint count = iAudioStreamObservers.Count();
1.812 + for ( TUint i(0); i < count; i++ )
1.813 + {
1.814 + iAudioStreamObservers[i]->FlushComplete(aError);
1.815 + }
1.816 + DP_OUT();
1.817 + }
1.818 +
1.819 +void CAudioStream::AllBuffersProcessed()
1.820 + {
1.821 + DP_CONTEXT(CAudioStream::AllBuffersProcessed *CD1*, CtxDevSound, DPLOCAL);
1.822 + DP_IN();
1.823 + TUint count = iAudioStreamObservers.Count();
1.824 + for ( TUint i(0); i < count; i++ )
1.825 + {
1.826 + iAudioStreamObservers[i]->ProcessingFinished();
1.827 + }
1.828 + DP_OUT();
1.829 + }
1.830 +
1.831 +void CAudioStream::ProcessingUnitError(TInt /*aError*/)
1.832 + {
1.833 + DP_CONTEXT(CAudioStream::ProcessingUnitError *CD1*, CtxDevSound, DPLOCAL);
1.834 + DP_IN();
1.835 + DP_OUT();
1.836 + }
1.837 +
1.838 +// ---------------------------------------------------------------------------
1.839 +// CAudioStream::RegisterAudioCodecObserver
1.840 +// ---------------------------------------------------------------------------
1.841 +TInt CAudioStream::RegisterAudioCodecObserver(MAudioCodecObserver& aObserver)
1.842 + {
1.843 + DP_CONTEXT(CAudioStream::RegisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
1.844 + DP_IN();
1.845 + TInt err = iAudioCodecObservers.Find(&aObserver);
1.846 + if(err == KErrNotFound)
1.847 + {
1.848 + err = iAudioCodecObservers.Append(&aObserver);
1.849 + }
1.850 + else
1.851 + {
1.852 + err = KErrAlreadyExists;
1.853 + }
1.854 + DP0_RET(err, "%d");
1.855 + }
1.856 +
1.857 +// ---------------------------------------------------------------------------
1.858 +// CAudioStream::UnregisterAudioCodecObserver
1.859 +// ---------------------------------------------------------------------------
1.860 +void CAudioStream::UnregisterAudioCodecObserver(MAudioCodecObserver& aObserver)
1.861 + {
1.862 + DP_CONTEXT(CAudioStream::UnregisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
1.863 + DP_IN();
1.864 + TInt idxOrErr = iAudioCodecObservers.Find(&aObserver);
1.865 + if( idxOrErr != KErrNotFound )
1.866 + {
1.867 + iAudioCodecObservers.Remove(idxOrErr);
1.868 + }
1.869 + DP_OUT();
1.870 + }
1.871 +
1.872 +void CAudioStream::GetSupportedAModesComplete(TInt /*aError*/)
1.873 + {
1.874 + DP_CONTEXT(CAudioStream::GetSupportedAModesComplete *CD1*, CtxDevSound, DPLOCAL);
1.875 + DP_IN();
1.876 + DP_OUT();
1.877 + }
1.878 +
1.879 +void CAudioStream::GetSupportedARatesComplete(TInt /*aError*/)
1.880 + {
1.881 + DP_CONTEXT(CAudioStream::GetSupportedARatesComplete *CD1*, CtxDevSound, DPLOCAL);
1.882 + DP_IN();
1.883 + DP_OUT();
1.884 + }
1.885 +
1.886 +// ---------------------------------------------------------------------------
1.887 +// CAudioStream::GetSupportedSampleRates
1.888 +// ---------------------------------------------------------------------------
1.889 +TInt CAudioStream::GetSupportedSampleRates(RArray<TInt>& aSupportedRates)
1.890 + {
1.891 + TInt err = (KErrNotReady);
1.892 + err = iCodec->SupportedRates(aSupportedRates);
1.893 + return err;
1.894 + }
1.895 +
1.896 +// ---------------------------------------------------------------------------
1.897 +// CAudioStream::GetSupportedModes
1.898 +// ---------------------------------------------------------------------------
1.899 +TInt CAudioStream::GetSupportedModes(RArray<TUid>& aSupportedModes)
1.900 + {
1.901 + TInt err = (KErrNotReady);
1.902 + err = iCodec->SupportedModes(aSupportedModes);
1.903 + return err;
1.904 + }
1.905 +
1.906 +// end of file