First public contribution.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include <mdaaudiooutputstream.h>
17 #include <mda/common/audio.h>
18 #include "mmfclientaudiooutputstream.h"
19 #include "mmfclientaudiostreamutils.h"
21 #include <mmf/common/mmfpaniccodes.h>
23 #define WAIT_FOR_READY_ACTIVE_OBJECTS
25 const TInt KMicroSecsInOneSec = 1000000;
26 const TInt KUnknownVolume = -1; // means "don't set", must be negative
27 const TInt KShutDownTimeInterval = 100000; //100 milli seconds
33 * @return CMdaAudioOutputStream*
36 EXPORT_C CMdaAudioOutputStream* CMdaAudioOutputStream::NewL(MMdaAudioOutputStreamCallback& aCallback,
37 CMdaServer* /*aServer = NULL*/)
39 return NewL(aCallback, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
46 * @return CMdaAudioOutputStream*
49 EXPORT_C CMdaAudioOutputStream* CMdaAudioOutputStream::NewL(MMdaAudioOutputStreamCallback& aCallback,
51 TInt aPref /*=EMdaPriorityPreferenceTimeAndQuality*/)
53 CMdaAudioOutputStream* self = new(ELeave) CMdaAudioOutputStream();
54 CleanupStack::PushL(self);
55 self->iProperties = CMMFMdaAudioOutputStream::NewL(aCallback, aPriority, aPref);
56 CleanupStack::Pop(self);
60 CMdaAudioOutputStream::CMdaAudioOutputStream()
64 CMdaAudioOutputStream::~CMdaAudioOutputStream()
69 void CMdaAudioOutputStream::SetAudioPropertiesL(TInt aSampleRate, TInt aChannels)
72 iProperties->SetAudioPropertiesL(aSampleRate, aChannels);
75 void CMdaAudioOutputStream::Open(TMdaPackage* aSettings)
78 iProperties->Open(aSettings);
81 TInt CMdaAudioOutputStream::MaxVolume()
84 return iProperties->MaxVolume();
87 TInt CMdaAudioOutputStream::Volume()
90 return iProperties->Volume();
93 void CMdaAudioOutputStream::SetVolume(const TInt aNewVolume)
96 iProperties->SetVolume(aNewVolume);
99 void CMdaAudioOutputStream::SetPriority(TInt aPriority, TInt aPref)
102 iProperties->SetPriority(aPriority, aPref);
105 void CMdaAudioOutputStream::WriteL(const TDesC8& aData)
108 iProperties->WriteL(aData);
111 void CMdaAudioOutputStream::Stop()
117 EXPORT_C TInt CMdaAudioOutputStream::Pause()
120 return iProperties->Pause();
123 EXPORT_C TInt CMdaAudioOutputStream::Resume()
126 return iProperties->Resume();
129 const TTimeIntervalMicroSeconds& CMdaAudioOutputStream::Position()
132 return iProperties->Position();
135 EXPORT_C void CMdaAudioOutputStream::SetBalanceL(TInt aBalance)
138 iProperties->SetBalanceL(aBalance);
141 EXPORT_C TInt CMdaAudioOutputStream::GetBalanceL() const
144 return iProperties->GetBalanceL();
147 EXPORT_C TInt CMdaAudioOutputStream::GetBytes()
150 return iProperties->GetBytes();
153 EXPORT_C TInt CMdaAudioOutputStream::KeepOpenAtEnd()
156 return iProperties->KeepOpenAtEnd();
159 EXPORT_C TInt CMdaAudioOutputStream::RequestStop()
162 return iProperties->RequestStop();
168 EXPORT_C void CMdaAudioOutputStream::SetDataTypeL(TFourCC aAudioType)
171 iProperties->SetDataTypeL(aAudioType);
178 EXPORT_C TFourCC CMdaAudioOutputStream::DataType() const
181 return iProperties->DataType();
184 EXPORT_C TAny* CMdaAudioOutputStream::CustomInterface(TUid aInterfaceId)
187 return iProperties->CustomInterface(aInterfaceId);
192 Registers the Event for Notification when resource is avaliable.
195 The audio player observer interface.
196 @param aNotificationEventUid
197 The event uid to notify the client.
198 @param aNotificationRegistrationData
199 Notification registration specific data.
201 @return An error code indicating if the registration was successful. KErrNone on success,
202 otherwise another of the system-wide error codes.
204 EXPORT_C TInt CMdaAudioOutputStream::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,
205 TUid aNotificationEventUid,
206 const TDesC8& aNotificationRegistrationData)
209 return iProperties->RegisterAudioResourceNotification(aCallback,aNotificationEventUid,aNotificationRegistrationData);
213 Cancels the registered notification event.
215 @param aNotificationEventUid
216 The Event to notify the client.
218 @return An error code indicating if the registration was successful. KErrNone on success,
219 otherwise another of the system-wide error codes.
221 EXPORT_C TInt CMdaAudioOutputStream::CancelRegisterAudioResourceNotification(TUid aNotificationEventUid)
224 return iProperties->CancelRegisterAudioResourceNotification(aNotificationEventUid);
228 Waits for the client to resume the play even after the default timer expires.
230 @return An error code indicating if the registration was successful. KErrNone on success,
231 otherwise another of the system-wide error codes.
233 EXPORT_C TInt CMdaAudioOutputStream::WillResumePlay()
236 return iProperties->WillResumePlay();
241 EToneFinishedNotSupported,
242 EBufferToBeEmptiedNotSupported,
243 ERecordErrorNotSupported,
244 EConvertErrorNotSupported,
245 EDeviceMessageNotSupported,
250 _LIT(KMmfMdaAosCategory, "CMmfMdaAudioOutputStream");
251 LOCAL_C void Panic(const TMmAosPanic aReason)
253 User::Panic(KMmfMdaAosCategory, aReason);
258 * 2 phase construction function
261 CMMFMdaAudioOutputStream* CMMFMdaAudioOutputStream::NewL(MMdaAudioOutputStreamCallback& aCallback)
263 return NewL(aCallback, EMdaPriorityNormal, EMdaPriorityPreferenceTimeAndQuality);
266 CMMFMdaAudioOutputStream* CMMFMdaAudioOutputStream::NewL(MMdaAudioOutputStreamCallback& aCallback, TInt aPriority, TInt aPref)
268 CMMFMdaAudioOutputStream* self = new(ELeave) CMMFMdaAudioOutputStream(aCallback);
269 CleanupStack::PushL(self);
270 self->ConstructL(aPriority, aPref);
271 CleanupStack::Pop(); // self
279 * @param "MMdaAudioOutputStreamCallback&"
280 * a reference to MMdaAudioOutputStreamCallback
281 * @param "TInt aPriority"
283 * @param "TInt aPref"
287 CMMFMdaAudioOutputStream::CMMFMdaAudioOutputStream(MMdaAudioOutputStreamCallback& aCallback)
288 : iCallback(aCallback), iState(EStopped)
290 iDataTypeCode.Set(TFourCC(' ','P','1','6'));
295 * Second phase constructor
298 void CMMFMdaAudioOutputStream::ConstructL(TInt aPriority, TInt aPref)
300 iDevSound = CMMFDevSound::NewL();
301 SetPriority(aPriority, aPref);
302 iDevSoundIgnoresUnderflow = iDevSound->QueryIgnoresUnderflow();
303 iFifo = new(ELeave) CMMFFifo<const TDesC8>();
304 iActiveCallback = new(ELeave) CActiveCallback(iCallback);
305 iActiveSchedulerWait = new(ELeave) CActiveSchedulerWait;
306 iShutDownTimer = CPeriodic::NewL(CActive::EPriorityStandard);
314 CMMFMdaAudioOutputStream::~CMMFMdaAudioOutputStream()
318 delete iActiveCallback;
319 delete iActiveSchedulerWait;
320 delete iShutDownTimer;
325 * Set audio output stream properties
327 * @param "TInt aSampleRate"
328 * a specified priority value
329 * @param "TInt aChannels"
330 * a specified preference value
333 void CMMFMdaAudioOutputStream::SetAudioPropertiesL(TInt aSampleRate, TInt aChannels)
335 if (iIsOpenState==EIsOpen)
337 RealSetAudioPropertiesL(aSampleRate, aChannels);
341 // cache params for application later
342 iSampleRate = aSampleRate;
343 iChannels = aChannels;
344 iVolume = KUnknownVolume;
345 iValuesCached = ETrue;
349 void CMMFMdaAudioOutputStream::RealSetAudioPropertiesL(TInt aSampleRate, TInt aChannels)
351 TMMFCapabilities config = iDevSound->Config();
352 config.iChannels = StreamUtils::MapChannelsMdaToMMFL(aChannels);
353 config.iRate = StreamUtils::MapSampleRateMdaToMMFL(aSampleRate);
354 iDevSound->SetConfigL(config);
359 * Open a audio ouptut stream
361 * @param "TMdaPackage* Settings"
362 * a pointer point to TMdaPackage
365 void CMMFMdaAudioOutputStream::Open(TMdaPackage* aSettings)
367 iIsOpenState = EIsOpening;
369 // Use settings to set audio properties after the dev sound has been
370 // successfully initialised. Note if the InitializeL() fails, something calls
371 // InitializeComplete() and the iValuesCached flag is cleared. Also note
372 // that if SetAudioPropertiesL() has already been called, there may already
374 if (aSettings && aSettings->Type().iUid == KUidMdaDataTypeSettingsDefine)
376 TMdaAudioDataSettings& audioSettings = *STATIC_CAST(TMdaAudioDataSettings*, aSettings);
377 //Caching these values, which are later set in InitializeComplete
378 iSampleRate = audioSettings.iSampleRate;
379 iChannels = audioSettings.iChannels;
380 iVolume = audioSettings.iVolume;
381 iValuesCached = ETrue;
384 TRAPD(err, iDevSound->InitializeL(*this, iDataTypeCode, EMMFStatePlaying));
387 InitializeComplete(err);
393 * To get the maximum volume level
396 * the maximum volume value in integer
399 TInt CMMFMdaAudioOutputStream::MaxVolume()
401 return iDevSound->MaxVolume();
406 * To get the current volume level
409 * the current volume value in integer
412 TInt CMMFMdaAudioOutputStream::Volume()
414 return iDevSound->Volume();
419 * Set audio output stream volume to the specified value
421 * @param "TInt aVolume"
422 * a specified volume value
425 void CMMFMdaAudioOutputStream::SetVolume(TInt aVolume)
427 iDevSound->SetVolume(aVolume);
432 * Set audio output stream balance
434 * @param "TInt aBalance"
435 * a specified balance value
438 void CMMFMdaAudioOutputStream::SetBalanceL(TInt aBalance)
440 // test and clip balance to min / max range [-100 <-> 100]
441 // clip rather than leave as this isn't a leaving function
442 if (aBalance < KMMFBalanceMaxLeft) aBalance = KMMFBalanceMaxLeft;
443 if (aBalance > KMMFBalanceMaxRight) aBalance = KMMFBalanceMaxRight;
445 // separate out left and right balance
448 StreamUtils::CalculateLeftRightBalance( left, right, aBalance );
450 // send the balance to SoundDevice
451 iDevSound->SetPlayBalanceL(left, right);
456 * To get the current balance value. This function may not return the same value
457 * as passed to SetBalanceL depending on the internal implementation in
458 * the underlying components.
461 * the current balance value in integer
464 TInt CMMFMdaAudioOutputStream::GetBalanceL() const
466 TInt rightBalance = 0;
467 TInt leftBalance = 0;
468 iDevSound->GetPlayBalanceL(leftBalance, rightBalance);
470 StreamUtils::CalculateBalance( balance, leftBalance, rightBalance );
476 * Set audio output stream priority
478 * @param "TInt aPriority"
479 * a specified priority value
480 * @param "TMdaPriorityPreference aPref"
481 * a specified preference value
484 void CMMFMdaAudioOutputStream::SetPriority(TInt aPriority, TInt aPref)
486 TMMFPrioritySettings settings;
487 settings.iPriority = aPriority;
488 settings.iPref = aPref;
489 iDevSound->SetPrioritySettings(settings);
494 * To write data to output stream
495 * Note that if framed data eg gsm610 is being streamed then the buffer
496 * size of aData should contain an intiger number of frames
498 * @param "const TDesC8& aData"
502 void CMMFMdaAudioOutputStream::WriteL(const TDesC8& aData)
504 if(iState==EStopping)
506 User::Leave(KErrNotReady);
508 iShutDownTimer->Cancel();
510 TMMFFifoItem<const TDesC8>* item = new(ELeave) TMMFFifoItem<const TDesC8>(aData);
511 iFifo->AddToFifo(*item);
513 if(iState == EStopped)
515 else if((iState == EPlaying) && (iBuffer != NULL))
516 { //if we are playing and we have a buffer waiting for data, use it.
517 BufferToBeFilled(iBuffer);
520 if(iEventHolder != KNullUid)
522 TInt err = iDevSound->RegisterAsClient(iEventHolder,iNotificationDataHolder);
523 iEventHolder = KNullUid;
524 iNotificationDataHolder = KNullDesC8;
527 iCallback.MaoscPlayComplete(err);
534 * If the audio stream is stopped, then notify the CDevSound to initilised play.
535 * The CDevSound will automatically start calling back for buffers.
537 void CMMFMdaAudioOutputStream::StartPlayL()
539 if (iState == EStopped)
542 iCurrentSamplesPlayed = 0;
543 iDevSound->PlayInitL();
552 * To stop write data to stream
555 void CMMFMdaAudioOutputStream::Stop()
557 iShutDownTimer->Cancel();
558 EmptyFifo(KErrAbort);
560 if(iState == EStopped)
565 // stop the operation
570 iCallback.MaoscPlayComplete(KErrCancel);
573 TInt CMMFMdaAudioOutputStream::RequestStop()
577 return KErrNotSupported;
580 if(iState==EStopped || iState==EStopping)
586 {//means all the client buffers are used up and waiting for more data
587 CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(iBuffer);
588 dataBuffer->Data().SetLength(0);
589 dataBuffer->SetLastBuffer(ETrue);
590 iDevSound->PlayData();
597 TInt CMMFMdaAudioOutputStream::KeepOpenAtEnd()
599 if(!iDevSoundIgnoresUnderflow)
601 return KErrNotSupported;
605 iKeepOpenAtEnd = ETrue;
612 * To pause send data to stream
615 TInt CMMFMdaAudioOutputStream::Pause()
617 if(iState != EPlaying)
622 else if(!iDevSound->IsResumeSupported())
624 return KErrNotSupported;
627 // pause the operation
635 * To resume send data to stream
638 TInt CMMFMdaAudioOutputStream::Resume()
641 if(iState != EPaused)
645 else if(!iDevSound->IsResumeSupported())
647 err = KErrNotSupported;
650 // resume the operation
653 err = iDevSound->Resume();
666 * To get the current position in the data stream
668 * @return "TTimeIntervalMicroSeconds&"
669 * the current position in integer
672 const TTimeIntervalMicroSeconds& CMMFMdaAudioOutputStream::Position()
674 TInt64 position = iDevSound->SamplesPlayed();
675 position = position * KMicroSecsInOneSec / StreamUtils::SampleRateAsValue(iDevSound->Config());
676 iPosition = (iState == EPlaying || iState == EStopping || iState == EPaused) ? position : 0; // Shouldn't need to check for playing but CMMFDevSound doesn't reset bytes played after a stop
682 * To return the current number of bytes rendered by audio hardware
683 * @return "the current current number of bytes rendered by audio hardware in integer"
686 TInt CMMFMdaAudioOutputStream::GetBytes()
688 return iDevSound->SamplesPlayed() * StreamUtils::BytesPerSample(iDevSound->Config());
694 void CMMFMdaAudioOutputStream::SetDataTypeL(TFourCC aAudioType)
696 if(iState != EStopped)
697 User::Leave(KErrServerBusy);
699 if(aAudioType == iDataTypeCode)
702 TMMFPrioritySettings prioritySettings;
703 prioritySettings.iState = EMMFStatePlaying;
704 RArray<TFourCC> supportedDataTypes;
706 CleanupClosePushL(supportedDataTypes);
708 TRAPD(err, iDevSound->GetSupportedInputDataTypesL(supportedDataTypes, prioritySettings));
712 if (supportedDataTypes.Find(aAudioType) == KErrNotFound)
714 User::Leave(KErrNotSupported);
716 //if match, set the 4CC of AudioType to match
717 iDataTypeCode.Set(aAudioType);
719 else //we had a real leave error from GetSupportedOuputDataTypesL
724 CleanupStack::PopAndDestroy(&supportedDataTypes);
726 if(iIsOpenState!=EIsNotOpen)
728 // need to recall or restart InitializeL() process
729 iDevSound->CancelInitialize(); // call just in case mid-InitializeL. No harm if not.
730 // if not supported then assume old DevSound behaviour anyway
731 // where InitializeL() implicitly cancels, so no harm either way
732 iIsOpenState = EIsOpening;
733 iInitCallFrmSetDataType = ETrue;
734 TRAPD(err, iDevSound->InitializeL(*this, iDataTypeCode, EMMFStatePlaying));
738 iIsOpenState = EIsNotOpen;
739 iInitCallFrmSetDataType = EFalse;
742 // In some implementations InitializeComplete is sent
743 // in context, so check before starting activeSchedulerWait.
744 else if(iIsOpenState == EIsOpening)
746 iInitializeState = KRequestPending;
747 iActiveSchedulerWait->Start();
749 iInitCallFrmSetDataType = EFalse;
750 User::LeaveIfError(iInitializeState);
757 TFourCC CMMFMdaAudioOutputStream::DataType() const
759 return iDataTypeCode;
762 TInt CMMFMdaAudioOutputStream::RegisterAudioResourceNotification(MMMFAudioResourceNotificationCallback& aCallback,TUid aNotificationEventUid,const TDesC8& aNotificationRegistrationData)
764 iAudioResourceNotificationCallBack = &aCallback;
765 TInt err = iDevSound->RegisterAsClient(aNotificationEventUid,aNotificationRegistrationData);
766 if(err == KErrNotReady)
768 iEventHolder = aNotificationEventUid;
769 iNotificationDataHolder = aNotificationRegistrationData;
772 iEventHolder = KNullUid;
773 iNotificationDataHolder = KNullDesC8;
777 TInt CMMFMdaAudioOutputStream::CancelRegisterAudioResourceNotification(TUid aNotificationEventId)
779 TInt err = iDevSound->CancelRegisterAsClient(aNotificationEventId);
780 if(err == KErrNotReady)
782 if(aNotificationEventId != KMMFEventCategoryAudioResourceAvailable)
784 return KErrNotSupported;
786 if(iEventHolder == KNullUid)
790 iEventHolder = KNullUid;
791 iNotificationDataHolder = KNullDesC8;
797 TInt CMMFMdaAudioOutputStream::WillResumePlay()
799 return iDevSound->WillResumePlay();
804 * To be called when intialize stream complete
806 * @param "TInt aError"
807 * error code, initialize stream succeed when aError = 0
810 void CMMFMdaAudioOutputStream::InitializeComplete(TInt aError)
813 if(err == KErrNone && iValuesCached)
815 TRAP(err, RealSetAudioPropertiesL(iSampleRate, iChannels));
816 if(err == KErrNone && iVolume>=0)
821 iValuesCached = EFalse; // whatever clear our cache
822 if(iIsOpenState == EIsOpening)
824 // Signal for the MaoscOpenComplete callback to be called asynchronously.Ignore if InitializeL is called from SetDataTypeL
825 if(!iInitCallFrmSetDataType)
827 iActiveCallback->Signal(err);
829 iIsOpenState = err ? EIsNotOpen : EIsOpen;
830 if(iInitializeState == KRequestPending)
832 iInitializeState = err;
833 iActiveSchedulerWait->AsyncStop();
837 iInitializeState = err;//Set the error if InitializeComplete is called in context of InitializeL.
847 void CMMFMdaAudioOutputStream::ToneFinished(TInt /*aError*/)
849 Panic(EToneFinishedNotSupported);
854 * Called when sound device need data
856 * @param "CMMFBuffer* aBuffer"
857 * a pointer point to CMMFBuffer, which is used to stored data
860 void CMMFMdaAudioOutputStream::BufferToBeFilled(CMMFBuffer* aBuffer)
862 if (iState == EPlaying || iState == EStopping)
864 TMMFFifoItem<const TDesC8>* firstItem = iFifo->Get();
865 //ASSERT firstItem != NULL
866 if (iFifoItemPos >= firstItem->GetData().Length())
868 // We've played all segments of the first buffer in the fifo so we can delete it
869 iFifo->RemoveFirstItem();
870 iCallback.MaoscBufferCopied(KErrNone, firstItem->GetData());
875 TMMFFifoItem<const TDesC8>* firstItem = iFifo->Get();
879 // Fill aBuffer with the next segment of the first buffer in the fifo
880 TDes8& fillDes = STATIC_CAST(CMMFDataBuffer*, aBuffer)->Data();
881 const TDesC8& readDes = firstItem->GetData();
882 TInt readLen = Min(readDes.Length()-iFifoItemPos, aBuffer->RequestSize());
883 fillDes = readDes.Mid(iFifoItemPos, readLen);
884 iFifoItemPos+=readLen; // so we know where the next segment in the fifo item starts
885 // Notify iDevSound the buffer is ready to be played
886 iDevSound->PlayData();
892 //keep a record of the supplied buffer and use it when/if more user data is in the FIFO
897 if (iDevSoundIgnoresUnderflow)
899 iCurrentSamplesPlayed = iDevSound->SamplesPlayed();
900 StartShutDownTimer();
903 else if(iState==EStopping)
905 CMMFDataBuffer* dataBuffer = static_cast<CMMFDataBuffer*>(aBuffer);
906 dataBuffer->Data().SetLength(0);
907 dataBuffer->SetLastBuffer(ETrue);
908 iDevSound->PlayData();
915 void CMMFMdaAudioOutputStream::StartShutDownTimer()
917 iShutDownTimer->Start(KShutDownTimeInterval, KShutDownTimeInterval, TCallBack(ShutDownTimerComplete,this));
920 TInt CMMFMdaAudioOutputStream::ShutDownTimerComplete(TAny* aAudioOutputStream)
922 CMMFMdaAudioOutputStream* audioOutputStream = static_cast<CMMFMdaAudioOutputStream*>(aAudioOutputStream);
923 audioOutputStream->DoShutDownTimerComplete();
927 void CMMFMdaAudioOutputStream::DoShutDownTimerComplete()
929 iShutDownTimer->Cancel();
930 TInt samplesPlayed = iDevSound->SamplesPlayed();
931 if (samplesPlayed == iCurrentSamplesPlayed)
936 iCallback.MaoscPlayComplete(KErrUnderflow);
939 {//desvound has not yet finished playing all the data. So wait for one more cycle
941 iCurrentSamplesPlayed = samplesPlayed;
942 StartShutDownTimer();
948 * Called when play operation complete, successfully or otherwise
950 * @param "TInt aError"
951 * an error value which will indicate playing successfully complete
952 * if error value is 0
955 void CMMFMdaAudioOutputStream::PlayError(TInt aError)
958 // if iDevSoundIgnoresUnderflow is true, then KErrUnderflow should not be produced by DevSound when we are not stopping
959 __ASSERT_DEBUG(!iDevSoundIgnoresUnderflow || !(err==KErrUnderflow && iState!=EStopping), Panic(EAOSStoppingError));
962 iShutDownTimer->Cancel();
963 if (err == KErrNone || err == KErrUnderflow)
965 if (!iFifo->IsEmpty())
967 // We live again - the Fifo still has some data. The sound device
968 // will have to be opened again though so there might be an
970 TRAP(err, StartPlayL());
980 // Note - KErrUnderflow will be reported even when all the buffers have
981 // successfully played
982 iCallback.MaoscPlayComplete(err);
985 void CMMFMdaAudioOutputStream::EmptyFifo(TInt aError)
987 // Delete all buffers in the fifo and notify the observer
988 TMMFFifoItem<const TDesC8>* firstItem;
989 while((firstItem = iFifo->Get()) != NULL)
991 iFifo->RemoveFirstItem();
992 iCallback.MaoscBufferCopied(aError, firstItem->GetData());
997 void CMMFMdaAudioOutputStream::SendEventToClient(const TMMFEvent& aEvent)
999 if (aEvent.iEventType == KMMFEventCategoryAudioResourceAvailable)
1001 // Retrieve the number of samples played
1002 // For the event type KMMFEventCategoryAudioResourceAvailable GetResourceNotificationData() returns
1003 // a package buffer as TMMFTimeIntervalMicroSecondsPckg, but the contents should be
1004 // converted to an integer and interpreted as the data returned is samples played,
1005 // but not as a microsecond value.
1006 TBuf8<TMMFAudioConfig::KNotificationDataBufferSize> notificationData;
1007 if (KErrNone != iDevSound->GetResourceNotificationData(aEvent.iEventType, notificationData))
1009 notificationData.SetLength(0);
1011 iAudioResourceNotificationCallBack->MarncResourceAvailable(aEvent.iEventType, notificationData);
1015 CMMFMdaAudioOutputStream::CActiveCallback::~CActiveCallback()
1020 CMMFMdaAudioOutputStream::CActiveCallback::CActiveCallback(MMdaAudioOutputStreamCallback& aCallback)
1021 : CActive(EPriorityStandard), iCallback(aCallback)
1023 CActiveScheduler::Add(this);
1026 void CMMFMdaAudioOutputStream::CActiveCallback::RunL()
1028 iCallback.MaoscOpenComplete(iStatus.Int());
1031 void CMMFMdaAudioOutputStream::CActiveCallback::DoCancel()
1035 void CMMFMdaAudioOutputStream::CActiveCallback::Signal(const TInt aReason)
1037 ASSERT(!IsActive());
1039 // Signal ourselves to run with the given completion code
1040 TRequestStatus* status = &iStatus;
1041 User::RequestComplete(status, aReason);
1051 void CMMFMdaAudioOutputStream::BufferToBeEmptied(CMMFBuffer* /*aBuffer*/)
1053 Panic(EBufferToBeEmptiedNotSupported);
1061 void CMMFMdaAudioOutputStream::RecordError(TInt /*aError*/)
1063 Panic(ERecordErrorNotSupported);
1071 void CMMFMdaAudioOutputStream::ConvertError(TInt /*aError*/)
1073 Panic(EConvertErrorNotSupported);
1081 void CMMFMdaAudioOutputStream::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /*aMsg*/)
1083 Panic(EDeviceMessageNotSupported);
1086 // CustomInferface - just pass on to DevSound.
1087 TAny* CMMFMdaAudioOutputStream::CustomInterface(TUid aInterfaceId)
1089 return iDevSound->CustomInterface(aInterfaceId);