os/mm/mmlibs/mmfw/MIDI/src/midiclientutilitybody.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include "midiclientutilitybody.h"
    17 
    18 const TInt KMimeLength         = 256;
    19 const TInt KMinChannel         = 0;
    20 const TInt KMaxChannel         = 15;
    21 const TInt KMinNote            = 0;
    22 const TInt KMaxNote            = 127;
    23 const TInt KMinNoteOnVelocity  = 0;
    24 const TInt KMaxNoteOnVelocity  = 127;
    25 const TInt KMinNoteOffVelocity = 0;
    26 const TInt KMaxNoteOffVelocity = 127;
    27 const TInt KMinInstrumentId    = 0;
    28 const TInt KMaxInstrumentId    = 127;
    29 
    30 
    31 CMidiClientUtility::CBody* CMidiClientUtility::CBody::NewL(CMidiClientUtility* aParent,
    32 														   MMidiClientUtilityObserver& aObserver, 
    33 														   TInt aPriority, 
    34 														   TInt aPref,
    35 														   TBool aUseSharedHeap)
    36 	{
    37 	CBody* self = new(ELeave) CBody(aParent, aObserver, aPriority, aPref);
    38 	CleanupStack::PushL(self);
    39 	self->ConstructL(aUseSharedHeap);
    40 	CleanupStack::Pop(self);
    41 	return self;
    42 	}
    43 
    44 CMidiClientUtility::CBody::CBody(CMidiClientUtility* aParent, 
    45 								 MMidiClientUtilityObserver& aObserver, 
    46 								 TInt aPriority, 
    47 								 TInt aPref) :
    48 	iObserver(aObserver),
    49 	iMidiControllerCommands(iController),
    50 	iDRMCustomCommands(iController)
    51 
    52 	{
    53 	iParent = aParent;
    54 	iState = EMidiStateClosedDisengaged;
    55 	iPrioritySettings.iPriority = aPriority;
    56 	iPrioritySettings.iPref = aPref;
    57 	iIntervalSec = ETrue;
    58 	iStopPosition = TTimeIntervalMicroSeconds(0);
    59 	}
    60 
    61 CMidiClientUtility::CBody::~CBody()
    62 	{
    63 	delete iAddDataSourceSinkAsync;
    64 	if (iMidiControllerEventMonitor)
    65 		iMidiControllerEventMonitor->Cancel();
    66 		
    67 	iController.Close();
    68 	delete iMidiControllerEventMonitor;
    69 	delete iMimeType;
    70 	delete iRepeatTrailingSilenceTimer;
    71 	delete iSource;
    72 	}
    73 
    74 void CMidiClientUtility::CBody::ConstructL(TBool aUseSharedHeap)
    75 	{
    76 	iMidiControllerEventMonitor = CMidiControllerEventMonitor::NewL(*this, iMidiControllerCommands, *iParent);
    77 	iMimeType = HBufC8::NewL(KMimeLength);
    78 		
    79 	RMMFControllerImplInfoArray controllers;
    80 	CleanupResetAndDestroyPushL(controllers);
    81 	CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC();
    82 
    83 	// Select the media IDs to allow
    84 	RArray<TUid> mediaIds;
    85 	CleanupClosePushL(mediaIds);
    86 	User::LeaveIfError(mediaIds.Append(KUidMediaTypeMidi));
    87 	cSelect->SetMediaIdsL(mediaIds,CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds);
    88 	CleanupStack::PopAndDestroy();//mediaIds
    89 	cSelect->ListImplementationsL(controllers);
    90 	// Open and configure a controller
    91 	User::LeaveIfError(DoOpen(controllers, KUidMmfAudioOutput, KNullDesC8, aUseSharedHeap));
    92 	CleanupStack::PopAndDestroy(2);//controllers, cSelect
    93 	iRepeatTrailingSilenceTimer = CRepeatTrailingSilenceTimer::NewL(*this);
    94 	iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this);
    95 	}
    96 
    97 void CMidiClientUtility::CBody::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle)
    98 	{
    99 	if (aError == KErrNone)
   100 		{
   101 		iSourceHandle = aHandle;
   102 		}
   103 	else
   104 		{
   105  		iMidiControllerEventMonitor->SelfComplete(aError);
   106 		}
   107 	}
   108 void CMidiClientUtility::CBody::OpenFile(const TDesC& aFileName)
   109 	{
   110 	TMMFFileConfig sourceCfg;
   111 	sourceCfg().iPath = aFileName;
   112 	// Add the data source to the controller. MmcuoStateChanged will be call on completition.
   113 	iAddDataSourceSinkAsync->AddDataSource(iController, KUidMmfFileSource, sourceCfg);
   114 	}
   115 
   116 void CMidiClientUtility::CBody::OpenFile(RFile& aFile)
   117 	{
   118 		// Add the data source to the controller. MmcuoStateChanged will be call on completition.
   119 	iAddDataSourceSinkAsync->AddFileHandleDataSource(iController, aFile);
   120 	}
   121 
   122 void CMidiClientUtility::CBody::OpenFile(const TMMSource& aSource)
   123 	{
   124 	TRAPD(err, DoOpenFileL(aSource));
   125 	if (err != KErrNone)
   126 		{
   127  		iMidiControllerEventMonitor->SelfComplete(err);
   128 		}
   129 	}
   130 	
   131 	
   132 void CMidiClientUtility::CBody::DoOpenFileL(const TMMSource& aSource)
   133 	{
   134 	delete iSource;
   135 	iSource = NULL;
   136 	iSource = CMMFileSourceSink::NewL(KUidMmfFileSource, aSource);
   137 	static_cast<CMMFileSourceSink*>(iSource)->EvaluateIntentL( aSource.Intent() );
   138 	iAddDataSourceSinkAsync->AddDataSource(iController, 
   139 								iSource->SourceSinkUid(),
   140 								iSource->SourceSinkData());
   141 	}
   142 
   143 void CMidiClientUtility::CBody::OpenDes(const TDesC8& aDescriptor)
   144 	{
   145 	TMMFDescriptorConfig sourceCfg;
   146 	sourceCfg().iDes = (TAny*)&aDescriptor;
   147 	sourceCfg().iDesThreadId = RThread().Id();
   148 	// Add the data source to the controller. MmcuoStateChanged will be call on completition.
   149 	iAddDataSourceSinkAsync->AddDataSource(iController, KUidMmfDescriptorSource, sourceCfg);
   150 	}
   151 
   152 void CMidiClientUtility::CBody::OpenUrl(const TDesC& aUrl,TInt aIapId,const TDesC8& /*aMimeType*/)
   153 	{
   154 	TRAPD(err, DoOpenUrlL(aUrl, aIapId));
   155 
   156 	if (err != KErrNone)
   157 		{
   158  		iMidiControllerEventMonitor->SelfComplete(err);
   159 		}
   160 
   161 	}
   162 
   163 void CMidiClientUtility::CBody::DoOpenUrlL(const TDesC& aUrl,TInt aIapId)
   164 	{
   165 	CMMFUrlParams* sourceCfg = CMMFUrlParams::NewLC(aUrl, aIapId);
   166 	CBufFlat* sourceCfgBuffer = sourceCfg->ExternalizeToCBufFlatLC();
   167 	// Add the data source to the controller. MmcuoStateChanged will be call on completition.
   168 	iAddDataSourceSinkAsync->AddDataSource(iController, KUidMmfUrlSource, sourceCfgBuffer->Ptr(0));
   169 	CleanupStack::PopAndDestroy(2, sourceCfg);//sourceCfgBuffer, sourceCfg
   170 	}
   171 
   172 void CMidiClientUtility::CBody::Close()
   173 	{
   174 	iMidiControllerCommands.Close();
   175 	}
   176 
   177 void CMidiClientUtility::CBody::Play()
   178 	{
   179 	TInt err = iController.Prime();
   180 	if (err==KErrNone)
   181 		{
   182 		err=iController.Play();
   183 		}
   184 	if (err!=KErrNone)
   185 		{
   186 		iMidiControllerEventMonitor->SelfComplete(err);
   187 		}
   188 	}
   189 
   190 void CMidiClientUtility::CBody::Stop(const TTimeIntervalMicroSeconds& aFadeOutDuration)
   191 	{
   192 	iMidiControllerCommands.Stop(aFadeOutDuration);
   193 	}
   194 	
   195 /**
   196  *
   197  * Returns the current state of the MIDI client utility
   198  * with regard to MIDI resources.
   199  *
   200  * @return "TMidiState" The current state of the utility
   201  *
   202  * @since	7.0s
   203  */
   204 
   205 TMidiState CMidiClientUtility::CBody::State() const
   206 	{
   207 	return iState;
   208 	}
   209 
   210 void CMidiClientUtility::CBody::PlayNoteL(TInt aChannel,TInt aNote,const TTimeIntervalMicroSeconds& aDuration,TInt aNoteOnVelocity,TInt aNoteOffVelocity)
   211 	{
   212 	if((aChannel >= KMinChannel && aChannel <= KMaxChannel) 
   213 	&& (aNote >= KMinNote && aNote <= KMaxNote) 
   214 	&& (aNoteOnVelocity >= KMinNoteOnVelocity && aNoteOnVelocity <= KMaxNoteOnVelocity) 
   215 	&& (aNoteOffVelocity >= KMinNoteOffVelocity && aNoteOffVelocity <= KMaxNoteOffVelocity))
   216 		{	
   217 		User::LeaveIfError(iMidiControllerCommands.PlayNote(aChannel, aNote, aDuration, aNoteOnVelocity, aNoteOffVelocity));
   218 		}
   219 	else
   220 		{
   221 		User::Leave(KErrArgument);
   222 		}
   223 	}
   224 
   225 void CMidiClientUtility::CBody::PlayNoteL(TInt aChannel,TInt aNote, const TTimeIntervalMicroSeconds& aStartTime, const TTimeIntervalMicroSeconds& aDuration, TInt aNoteOnVelocity, TInt aNoteOffVelocity)
   226 	{
   227 	if((aChannel >= KMinChannel && aChannel <= KMaxChannel) 
   228 	&& (aNote >= KMinNote && aNote <= KMaxNote) 
   229 	&& (aNoteOnVelocity >= KMinNoteOnVelocity && aNoteOnVelocity <= KMaxNoteOnVelocity) 
   230 	&& (aNoteOffVelocity >= KMinNoteOffVelocity && aNoteOffVelocity <= KMaxNoteOffVelocity))
   231 		{
   232 		User::LeaveIfError(iMidiControllerCommands.PlayNote(aChannel, aNote, aStartTime, aDuration, aNoteOnVelocity, aNoteOffVelocity));
   233 		}
   234 	else
   235 		{
   236 		User::Leave(KErrArgument);
   237 		}
   238 	}
   239 
   240 void CMidiClientUtility::CBody::StopNotes(TInt aChannel)
   241 	{
   242 	if(aChannel >= KMinChannel && aChannel <= KMaxChannel) 
   243 		{
   244 		iMidiControllerCommands.StopNotes(aChannel);
   245 		}
   246 	}
   247 
   248 void CMidiClientUtility::CBody::NoteOnL(TInt aChannel,TInt aNote,TInt aVelocity)
   249 	{
   250 	if((aChannel >= KMinChannel && aChannel <= KMaxChannel) 
   251 	&& (aNote >= KMinNote && aNote <= KMaxNote) 
   252 	&& (aVelocity >= KMinNoteOnVelocity && aVelocity <= KMaxNoteOnVelocity))
   253 		{
   254 		User::LeaveIfError(iMidiControllerCommands.NoteOn(aChannel, aNote, aVelocity));
   255 		}
   256 	else
   257 		{
   258 		User::Leave(KErrArgument);
   259 		}
   260 	}
   261 
   262 void CMidiClientUtility::CBody::NoteOffL(TInt aChannel,TInt aNote,TInt aVelocity)
   263 	{
   264 	if((aChannel >= KMinChannel && aChannel <= KMaxChannel) 
   265 	&& (aNote >= KMinNote && aNote <= KMaxNote) 
   266 	&& (aVelocity >= KMinNoteOffVelocity && aVelocity <= KMaxNoteOffVelocity))
   267 		{
   268 		User::LeaveIfError(iMidiControllerCommands.NoteOff(aChannel, aNote, aVelocity));
   269 		}
   270 	else
   271 		{
   272 		User::Leave(KErrArgument);
   273 		}
   274 	}
   275 
   276 TInt CMidiClientUtility::CBody::PlaybackRateL() const
   277 	{
   278 	TInt rate;
   279 	User::LeaveIfError(iMidiControllerCommands.PlaybackRate(rate));
   280 	return rate;
   281 	}
   282 
   283 void CMidiClientUtility::CBody::SetPlaybackRateL(TInt aRate)
   284 	{
   285 	User::LeaveIfError(iMidiControllerCommands.SetPlaybackRate(aRate));
   286 	}
   287 
   288 TInt CMidiClientUtility::CBody::MaxPlaybackRateL() const
   289 	{
   290 	TInt maxRate;
   291 	User::LeaveIfError(iMidiControllerCommands.MaxPlaybackRate(maxRate));
   292 	return maxRate;
   293 	}
   294 
   295 TInt CMidiClientUtility::CBody::MinPlaybackRateL() const
   296 	{
   297 	TInt minRate;
   298 	User::LeaveIfError(iMidiControllerCommands.MinPlaybackRate(minRate));
   299 	return minRate;
   300 	}
   301 
   302 
   303 TInt CMidiClientUtility::CBody::TempoMicroBeatsPerMinuteL() const
   304 	{
   305 	TInt microBeatsPerMinute;
   306 	User::LeaveIfError(iMidiControllerCommands.TempoMicroBeatsPerMinute(microBeatsPerMinute));
   307 	return microBeatsPerMinute;
   308 	}
   309 
   310 void CMidiClientUtility::CBody::SetTempoL(TInt aMicroBeatsPerMinute)
   311 	{
   312 	if(aMicroBeatsPerMinute > 0)
   313 		{
   314 		User::LeaveIfError(iMidiControllerCommands.SetTempo(aMicroBeatsPerMinute));
   315 		}
   316 	else
   317 		{
   318 		User::Leave(KErrArgument);
   319 		}
   320 	}
   321 
   322 TInt CMidiClientUtility::CBody::PitchTranspositionCentsL() const
   323 	{
   324 	TInt cents;
   325 	User::LeaveIfError(iMidiControllerCommands.PitchTranspositionCents(cents));
   326 	return cents;
   327 	}
   328 
   329 TInt CMidiClientUtility::CBody::SetPitchTranspositionL(TInt aCents)
   330 	{
   331 	TInt pitchApplied = 0;
   332 	//we do not check aCents value - it is expected the controller will report KErrArgument
   333 	//if the pitch level is not supported.
   334 	User::LeaveIfError(iMidiControllerCommands.SetPitchTransposition(aCents, pitchApplied));
   335 
   336 	return pitchApplied;
   337 	}
   338 
   339 TTimeIntervalMicroSeconds CMidiClientUtility::CBody::DurationMicroSecondsL() const
   340 	{
   341 	TTimeIntervalMicroSeconds duration;
   342 	User::LeaveIfError(iController.GetDuration(duration));
   343 	return duration;
   344 	}
   345 
   346 TInt64 CMidiClientUtility::CBody::DurationMicroBeatsL() const
   347 	{
   348 	TInt64 duration;
   349 	User::LeaveIfError(iMidiControllerCommands.DurationMicroBeats(duration));
   350 	return duration;
   351 	}
   352 
   353 TInt CMidiClientUtility::CBody::NumTracksL() const
   354 	{
   355 	TInt tracks;
   356 	User::LeaveIfError(iMidiControllerCommands.NumTracks(tracks));
   357 	return tracks;
   358 	}
   359 
   360 void CMidiClientUtility::CBody::SetTrackMuteL(TInt aTrack, TBool aMuted) const
   361 	{
   362 	TInt numTracks = NumTracksL();
   363 	if((aTrack >= 0) && (aTrack < numTracks))
   364 		{
   365 		User::LeaveIfError(iMidiControllerCommands.SetTrackMute(aTrack, aMuted));
   366 		}
   367 	else
   368 		{
   369 		User::Leave(KErrArgument);
   370 		}
   371 	}
   372 
   373 const TDesC8& CMidiClientUtility::CBody::MimeTypeL()
   374 	{
   375 	TPtr8 des = iMimeType->Des();
   376 	User::LeaveIfError(iMidiControllerCommands.MimeType(des));
   377 	return *iMimeType;
   378 	}
   379 
   380 TTimeIntervalMicroSeconds CMidiClientUtility::CBody::PositionMicroSecondsL() const
   381 	{
   382 	TTimeIntervalMicroSeconds position;
   383 	User::LeaveIfError(iController.GetPosition(position));
   384 	return position;
   385 	}
   386 
   387 void CMidiClientUtility::CBody::SetPositionMicroSecondsL(const TTimeIntervalMicroSeconds& aPosition)
   388 	{
   389 	TTimeIntervalMicroSeconds maxPosition = DurationMicroSecondsL();
   390 	TTimeIntervalMicroSeconds minPosition(0);
   391 
   392 	TTimeIntervalMicroSeconds position = aPosition;
   393 	if (aPosition > maxPosition)
   394 		{
   395 		position = maxPosition;
   396 		}
   397 	if (aPosition < minPosition)
   398 		{
   399 		position = minPosition;
   400 		}
   401 	User::LeaveIfError(iController.SetPosition(position));
   402 	}
   403 
   404 TInt64 CMidiClientUtility::CBody::PositionMicroBeatsL() const
   405 	{
   406 	TInt64 position;
   407 	User::LeaveIfError(iMidiControllerCommands.PositionMicroBeats(position));
   408 	return position;
   409 	}
   410 
   411 void CMidiClientUtility::CBody::SetPositionMicroBeatsL(TInt64 aMicroBeats)
   412 	{
   413 	TInt64 maxPosition = DurationMicroBeatsL();
   414 	TInt64 minPosition(0);
   415 
   416 	TInt64 position = aMicroBeats;
   417 	if (aMicroBeats > maxPosition)
   418 		{
   419 		position = maxPosition;
   420 		}
   421 	if (aMicroBeats < minPosition)
   422 		{
   423 		position = minPosition;
   424 		}
   425 	User::LeaveIfError(iMidiControllerCommands.SetPositionMicroBeats(position));
   426 	}
   427 
   428 void CMidiClientUtility::CBody::SetSyncUpdateCallbackIntervalL(const TTimeIntervalMicroSeconds& aMicroSeconds, TInt64 aMicroBeats)
   429 	{
   430 	
   431 	if((aMicroSeconds > TTimeIntervalMicroSeconds(0)) || (aMicroSeconds == TTimeIntervalMicroSeconds(0) && aMicroBeats == 0))
   432 		{
   433 		iIntervalSec = ETrue;
   434 		}
   435 	else 
   436 		{
   437 		if (aMicroBeats > 0)
   438 			{
   439 			iIntervalSec = EFalse;
   440 			}
   441 		else
   442 			{
   443 			User::Leave(KErrArgument);
   444 			}
   445 		}
   446 	
   447 	User::LeaveIfError(iMidiControllerCommands.SetSyncUpdateCallbackInterval(aMicroSeconds, aMicroBeats));
   448 	}
   449 
   450 TInt CMidiClientUtility::CBody::SendMessageL(const TDesC8& aMidiMessage)
   451 	{
   452 	TInt numByteProc;
   453 	User::LeaveIfError(iMidiControllerCommands.SendMessage(aMidiMessage, numByteProc));
   454 	return numByteProc;
   455 	}
   456 
   457 TInt CMidiClientUtility::CBody::SendMessageL(const TDesC8& aMidiMessage,const TTimeIntervalMicroSeconds& aTime)
   458 	{
   459 	TInt numByteProc;
   460 	User::LeaveIfError(iMidiControllerCommands.SendMessage(aMidiMessage, aTime, numByteProc));
   461 	return numByteProc;
   462 	}
   463 
   464 void CMidiClientUtility::CBody::SendMipMessageL(const RArray<TMipMessageEntry>& aEntry)
   465 	{
   466 	User::LeaveIfError(iMidiControllerCommands.SendMipMessage(aEntry));
   467 	}
   468 
   469 TInt CMidiClientUtility::CBody::NumberOfBanksL(TBool aCustom) const
   470 	{
   471 	TInt numBanks;
   472 	User::LeaveIfError(iMidiControllerCommands.NumberOfBanks(aCustom, numBanks));
   473 	return numBanks;
   474 	}
   475 
   476 TInt CMidiClientUtility::CBody::GetBankIdL(TBool aCustom,TInt aBankIndex) const
   477 	{
   478 	TInt numBanks = NumberOfBanksL(aCustom);
   479 	TInt bankId = 0;
   480 	if(aBankIndex >= 0 && aBankIndex < numBanks)
   481 		{
   482 		User::LeaveIfError(iMidiControllerCommands.GetBankId(aCustom, aBankIndex, bankId));
   483 		}
   484 	else
   485 		{
   486 		User::Leave(KErrArgument);
   487 		}
   488 	return bankId;
   489 	}
   490 
   491 void CMidiClientUtility::CBody::LoadCustomBankL(const TDesC& aFileName,TInt& aBankCollectionIndex)
   492 	{
   493 	User::LeaveIfError(iMidiControllerCommands.LoadCustomBank(aFileName, aBankCollectionIndex));
   494 	}
   495 
   496 void CMidiClientUtility::CBody::UnloadCustomBankL(TInt aBankCollectionIndex)
   497 	{
   498 	User::LeaveIfError(iMidiControllerCommands.UnloadCustomBank(aBankCollectionIndex));
   499 	}
   500 
   501 TBool CMidiClientUtility::CBody::CustomBankLoadedL(TInt aBankCollectionIndex) const
   502 	{
   503 	TBool bankLoaded;
   504 	User::LeaveIfError(iMidiControllerCommands.CustomBankLoaded(aBankCollectionIndex, bankLoaded));
   505 	return bankLoaded;
   506 	}
   507 
   508 void CMidiClientUtility::CBody::UnloadAllCustomBanksL()
   509 	{
   510 	User::LeaveIfError(iMidiControllerCommands.UnloadAllCustomBanks());
   511 	}
   512 
   513 TInt CMidiClientUtility::CBody::NumberOfInstrumentsL(TInt aBankId,TBool aCustom) const
   514 	{
   515 	TInt numInstruments;
   516 	User::LeaveIfError(iMidiControllerCommands.NumberOfInstruments(aBankId, aCustom, numInstruments));
   517 	return numInstruments;
   518 	}
   519 
   520 TInt CMidiClientUtility::CBody::GetInstrumentIdL(TInt aBankId,TBool aCustom,TInt aInstrumentIndex) const
   521 	{
   522 	TInt numInstruments = NumberOfInstrumentsL(aBankId, aCustom);
   523 	TInt instrumentId = 0;
   524 	if(aInstrumentIndex >=0 && aInstrumentIndex < numInstruments)
   525 		{
   526 		User::LeaveIfError(iMidiControllerCommands.GetInstrumentId(aBankId, aCustom, aInstrumentIndex, instrumentId));
   527 		}
   528 	else
   529 		{
   530 		User::Leave(KErrArgument);
   531 		}
   532 	return instrumentId;
   533 	}
   534 
   535 HBufC* CMidiClientUtility::CBody::InstrumentNameL(TInt aBankId, TBool aCustom, TInt aInstrumentId) const
   536 	{
   537 	HBufC* instrumentName = NULL;
   538 
   539 	if(aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId)
   540 		{
   541 		instrumentName = iMidiControllerCommands.InstrumentNameL(aBankId, aCustom, aInstrumentId);
   542 		}
   543 	else
   544 		{
   545 		User::Leave(KErrArgument);
   546 		}
   547 
   548 	return instrumentName;
   549 	}
   550 
   551 void CMidiClientUtility::CBody::SetInstrumentL(TInt aChannel,TInt aBankId,TInt aInstrumentId)
   552 	{
   553 	if((aChannel >= KMinChannel && aChannel <= KMaxChannel)  
   554 	&& (aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId))
   555 		{
   556 		User::LeaveIfError(iMidiControllerCommands.SetInstrument(aChannel, aBankId, aInstrumentId));
   557 		}
   558 	else
   559 		{
   560 		User::Leave(KErrArgument);
   561 		}
   562 	}
   563 
   564 void CMidiClientUtility::CBody::LoadCustomInstrumentL(const TDesC& aFileName, TInt aFileBankId, TInt aFileInstrumentId, TInt aMemoryBankId, TInt aMemoryInstrumentId)
   565 	{
   566 	if((aFileInstrumentId >= KMinInstrumentId && aFileInstrumentId <= KMaxInstrumentId) 
   567 	&& (aMemoryInstrumentId >= KMinInstrumentId && aMemoryInstrumentId <= KMaxInstrumentId))
   568 		{
   569 		User::LeaveIfError(iMidiControllerCommands.LoadCustomInstrument(aFileName, aFileBankId, aFileInstrumentId, aMemoryBankId, aMemoryInstrumentId));
   570 		}	
   571 	else
   572 		{
   573 		User::Leave(KErrArgument);
   574 		}
   575 	}
   576 
   577 void CMidiClientUtility::CBody::UnloadCustomInstrumentL(TInt aCustomBankId,TInt aInstrumentId)
   578 	{
   579 	if(aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId)
   580 		{
   581 		User::LeaveIfError(iMidiControllerCommands.UnloadCustomInstrument(aCustomBankId, aInstrumentId));
   582 		}
   583 	else
   584 		{
   585 		User::Leave(KErrArgument);
   586 		}
   587 	}
   588 
   589 HBufC* CMidiClientUtility::CBody::PercussionKeyNameL(TInt aNote, TInt aBankId, TBool aCustom, TInt aInstrumentId) const
   590 	{
   591 	HBufC* pKeyName = NULL;
   592 
   593 	if((aNote >= KMinNote && aNote <= KMaxNote) 
   594 	&& (aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId))
   595 		{
   596 		pKeyName = iMidiControllerCommands.PercussionKeyNameL(aNote, aBankId, aCustom, aInstrumentId);
   597 		}
   598 	else
   599 		{
   600 		User::Leave(KErrArgument);
   601 		}
   602 
   603 	return pKeyName;
   604 	}
   605 
   606 void CMidiClientUtility::CBody::StopTimeL(TTimeIntervalMicroSeconds& aStopTime) const
   607 	{
   608 	User::LeaveIfError(iMidiControllerCommands.StopTime(aStopTime));
   609 	}
   610 
   611 void CMidiClientUtility::CBody::SetStopTimeL(const TTimeIntervalMicroSeconds& aStopTime)
   612 	{
   613 	TTimeIntervalMicroSeconds duration = DurationMicroSecondsL();
   614 	if(aStopTime >= TTimeIntervalMicroSeconds(0) && aStopTime <= duration)
   615 		{
   616 		User::LeaveIfError(iMidiControllerCommands.SetStopTime(aStopTime));
   617 		}
   618 	else
   619 		{
   620 		User::Leave(KErrArgument);
   621 		}
   622 	}
   623 
   624 void CMidiClientUtility::CBody::SetRepeatsL(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence)
   625 	{
   626 	if((aRepeatNumberOfTimes >= 0) && (aTrailingSilence >= TTimeIntervalMicroSeconds(0)))
   627 		{
   628 		User::LeaveIfError(iMidiControllerCommands.SetRepeats(aRepeatNumberOfTimes, aTrailingSilence));
   629 		}
   630 	else
   631 		{
   632 		User::Leave(KErrArgument);
   633 		}	
   634 	}
   635 
   636 TInt CMidiClientUtility::CBody::PolyphonyL() const
   637 	{
   638 	TInt numNotes;
   639 	TInt maxPoly = MaxPolyphonyL();
   640 	User::LeaveIfError(iMidiControllerCommands.Polyphony(numNotes));
   641 	if(maxPoly <= numNotes)
   642 		{
   643 		return maxPoly;
   644 		}
   645 	else
   646 		{
   647 		return numNotes;	
   648 		}
   649 	}
   650 
   651 TInt CMidiClientUtility::CBody::MaxPolyphonyL() const
   652 	{
   653 	TInt maxNotes;
   654 	User::LeaveIfError(iMidiControllerCommands.MaxPolyphony(maxNotes));
   655 	return maxNotes;
   656 	}
   657 
   658 TInt CMidiClientUtility::CBody::ChannelsSupportedL() const
   659 	{
   660 	TInt channels;
   661 	User::LeaveIfError(iMidiControllerCommands.ChannelsSupported(channels));
   662 	return channels;
   663 	}
   664 
   665 TReal32 CMidiClientUtility::CBody::ChannelVolumeL(TInt aChannel) const
   666 	{
   667 	TReal32 channelVol;
   668 	if(aChannel >= KMinChannel && aChannel <= KMaxChannel) 
   669 		{
   670 		User::LeaveIfError(iMidiControllerCommands.ChannelVolume(aChannel, channelVol));
   671 		}
   672 	else
   673 		{
   674 		User::Leave(KErrArgument);	
   675 		}
   676 	return channelVol;
   677 	}
   678 
   679 TReal32 CMidiClientUtility::CBody::MaxChannelVolumeL() const
   680 	{
   681 	TReal32 maxChanVol;
   682 	User::LeaveIfError(iMidiControllerCommands.MaxChannelVolume(maxChanVol));
   683 	return maxChanVol;
   684 	}
   685 
   686 void CMidiClientUtility::CBody::SetChannelVolumeL(TInt aChannel,TReal32 aVolume)
   687 	{
   688 	TReal32 maxChanVol = MaxChannelVolumeL();
   689 	if((aChannel >= KMinChannel && aChannel <= KMaxChannel) && aVolume <= maxChanVol)
   690 		{
   691 		User::LeaveIfError(iMidiControllerCommands.SetChannelVolume(aChannel, aVolume));
   692 		}
   693 	else
   694 		{
   695 		User::Leave(KErrArgument);
   696 		}
   697 	}
   698 
   699 void CMidiClientUtility::CBody::SetChannelMuteL(TInt aChannel,TBool aMuted)
   700 	{
   701 	if(aChannel >= KMinChannel && aChannel <= KMaxChannel)
   702 		{
   703 		User::LeaveIfError(iMidiControllerCommands.SetChannelMute(aChannel, aMuted));
   704 		}
   705 	else
   706 		{
   707 		User::Leave(KErrArgument);
   708 		}
   709 	}
   710 
   711 TInt CMidiClientUtility::CBody::VolumeL() const
   712 	{
   713 	TInt vol;
   714 	User::LeaveIfError(iMidiControllerCommands.Volume(vol));
   715 	return vol;
   716 	}
   717 
   718 TInt CMidiClientUtility::CBody::MaxVolumeL() const
   719 	{
   720 	TInt maxVol;
   721 	User::LeaveIfError(iMidiControllerCommands.MaxVolume(maxVol));
   722 	return maxVol;
   723 	}
   724 
   725 void CMidiClientUtility::CBody::SetVolumeL(TInt aVolume)
   726 	{
   727 	User::LeaveIfError(iMidiControllerCommands.SetVolume(aVolume));
   728 	}
   729 
   730 void CMidiClientUtility::CBody::SetVolumeRampL(const TTimeIntervalMicroSeconds& aRampDuration)
   731 	{
   732 	User::LeaveIfError(iMidiControllerCommands.SetVolumeRamp(aRampDuration));
   733 	}
   734 
   735 
   736 TInt CMidiClientUtility::CBody::GetBalanceL() const
   737 	{
   738 	TInt balance;
   739 	User::LeaveIfError(iMidiControllerCommands.GetBalance(balance));
   740 	return balance;
   741 	}
   742 
   743 void CMidiClientUtility::CBody::SetBalanceL(TInt aBalance)
   744 	{
   745 	User::LeaveIfError(iMidiControllerCommands.SetBalance(aBalance));
   746 	}
   747 
   748 void CMidiClientUtility::CBody::SetPriorityL(TInt aPriority, TInt aPref)
   749 	{
   750 	TMMFPrioritySettings priority;
   751 	priority.iPriority = aPriority;
   752 	priority.iPref = aPref;
   753 
   754 	User::LeaveIfError(iController.SetPrioritySettings(priority));
   755 	}
   756 
   757 TInt CMidiClientUtility::CBody::NumberOfMetaDataEntriesL() const
   758 	{
   759 	TInt numMetaData;
   760 	User::LeaveIfError(iController.GetNumberOfMetaDataEntries(numMetaData));
   761 	return numMetaData;
   762 	}
   763 
   764 CMMFMetaDataEntry* CMidiClientUtility::CBody::GetMetaDataEntryL(TInt aMetaDataIndex) const
   765 	{
   766 	CMMFMetaDataEntry* metaDataEntry = iController.GetMetaDataEntryL(aMetaDataIndex);
   767 	return metaDataEntry;
   768 	}
   769 
   770 void CMidiClientUtility::CBody::CustomCommandSyncL(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom)
   771 	{
   772 	User::LeaveIfError(iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom));
   773 	}
   774 
   775 void CMidiClientUtility::CBody::CustomCommandSyncL(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2)
   776 	{
   777 	User::LeaveIfError(iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2));
   778 	}
   779 
   780 void CMidiClientUtility::CBody::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus)
   781 	{
   782 	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus);
   783 	}
   784 
   785 void CMidiClientUtility::CBody::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus)
   786 	{
   787 	iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus);
   788 	}
   789 
   790 MMMFDRMCustomCommand* CMidiClientUtility::CBody::GetDRMCustomCommand()
   791 	{
   792 	if (iDRMCustomCommands.IsSupported())
   793 		{
   794 		return static_cast<MMMFDRMCustomCommand*>(&iDRMCustomCommands);
   795 		}
   796 	return NULL;
   797 	}
   798 	
   799 TInt CMidiClientUtility::CBody::DoOpen(const RMMFControllerImplInfoArray& aControllers, TUid aSinkUid, const TDesC8& aSinkData, TBool aUseSharedHeap)
   800 	{
   801 	// Make sure any existing controller is closed.
   802 	iMidiControllerEventMonitor->Cancel();
   803 	iController.Close();
   804 
   805 	// Try opening and configuring each controller in turn
   806 	TInt error = KErrNotSupported;
   807 	TInt index = 0;
   808 	while (error)
   809 		{
   810 		// Break if we're at the end of the array of controllers
   811 		if (index >= aControllers.Count())
   812 			break;
   813 
   814 		// Open the controller
   815 		error = iController.Open(aControllers[index]->Uid(), iPrioritySettings, aUseSharedHeap);
   816 
   817 		// If the controller was opened without error, start receiving events from it.
   818 		if (error==KErrNone)
   819 			{
   820 			iMidiControllerEventMonitor->Start();
   821 			}
   822 
   823 		// Add the data sink
   824 		if (error==KErrNone)
   825 			error = iController.AddDataSink(aSinkUid, aSinkData, iSinkHandle);
   826 
   827 		// If an error occurred in any of the above, close the controller.
   828 		if (error!=KErrNone)
   829 			{
   830 			iMidiControllerEventMonitor->Cancel();
   831 			iController.Close();
   832 			}
   833 
   834 		// increment index
   835 		index++;
   836 		}
   837 
   838 	return error;
   839 	}
   840 
   841    void CMidiClientUtility::CBody::HandleMidiEvent(const CMMFMidiEvent& aEvent)
   842    	{
   843    	if(aEvent.iEventType == KMMFEventCategoryMidiOpenDataSourceComplete ||
   844    	   aEvent.iEventType == KMMFEventCategoryMidiClose ||
   845    	   aEvent.iEventType == KMMFEventCategoryMidiPrime ||
   846    	   aEvent.iEventType == KMMFEventCategoryMidiPlaying ||
   847    	   aEvent.iEventType == KMMFEventCategoryMidiPlaybackIncompatible ||
   848    	   aEvent.iEventType == KMMFEventCategoryMidiPlaybackSilent)
   849    		{
   850    		iState = aEvent.iNewState;
   851    		iObserver.MmcuoStateChanged(aEvent.iOldState, aEvent.iNewState, aEvent.iMicroSeconds, aEvent.iErrorCode);
   852    		
   853    		if (aEvent.iEventType == KMMFEventCategoryMidiClose)
   854    			{
   855 			if (iSourceHandle.DestinationHandle())
   856 				{
   857 				iController.RemoveDataSource(iSourceHandle);
   858 				}
   859 			}	
   860  		}
   861    	else if(aEvent.iEventType == KMMFEventCategoryMidiPlayingComplete)
   862    		{
   863  		iState = aEvent.iNewState;
   864    		iObserver.MmcuoStateChanged(aEvent.iOldState, aEvent.iNewState, aEvent.iMicroSeconds, aEvent.iErrorCode);
   865    		}
   866    	else if(aEvent.iEventType == KMMFEventCategoryMidiSyncUpdate)
   867    		{
   868    		iObserver.MmcuoSyncUpdate(aEvent.iMicroSeconds, aEvent.iMicroBeats);
   869    		}
   870    	else if(aEvent.iEventType == KMMFEventCategoryTempoChanged)
   871    		{
   872    		iObserver.MmcuoTempoChanged(aEvent.iTempoMicroBeats);
   873    		}
   874    	else if(aEvent.iEventType == KMMFEventCategoryVolumeChanged)
   875    		{
   876    		iObserver.MmcuoVolumeChanged(aEvent.iChannel, aEvent.iVolumeInDecibels);
   877    		}
   878    	else if(aEvent.iEventType == KMMFEventCategoryMuteChanged)
   879    		{
   880    		iObserver.MmcuoMuteChanged(aEvent.iChannel, aEvent.iMute);
   881    		}
   882    	else if(aEvent.iEventType == KMMFEventCategoryMetaDataEntryFound)
   883    		{
   884    		iObserver.MmcuoMetaDataEntryFound(aEvent.iMetaDataEntryId, aEvent.iMicroSeconds);
   885    		}
   886    	else if(aEvent.iEventType == KMMFEventCategoryMipMessageReceived)
   887    		{
   888    		iObserver.MmcuoMipMessageReceived(aEvent.iMipMessage);
   889    		}
   890    	else if(aEvent.iEventType == KMMFEventCategoryPolyphonyChanged)
   891    		{
   892    		iObserver.MmcuoPolyphonyChanged(aEvent.iPolyphony);
   893    		}
   894    	else if(aEvent.iEventType == KMMFEventCategoryInstrumentChanged)
   895    		{
   896    		iObserver.MmcuoInstrumentChanged(aEvent.iChannel,aEvent.iBankId,aEvent.iInstrumentId);
   897    		}
   898    	else if((iState == EMidiStateOpenPlaying) || (iState == EMidiStatePlaybackIncompatible) || 
   899    			(iState == EMidiStatePlaybackSilent) || (iState == EMidiStateClosedEngaged) ||
   900    			(iState == EMidiStateOpenEngaged))
   901    		{
   902  		iState = aEvent.iNewState;
   903    		iObserver.MmcuoStateChanged(aEvent.iOldState, aEvent.iNewState, aEvent.iMicroSeconds, aEvent.iErrorCode);
   904 
   905    		}
   906    	else if (aEvent.iEventType == KMMFErrorCategoryControllerGeneralError)
   907    		{
   908    		iObserver.MmcuoStateChanged(iState, iState, TTimeIntervalMicroSeconds(0), aEvent.iErrorCode);
   909    		}
   910    	else
   911    		{
   912    		// xxx - what do we do when we don't understand the error type?
   913    		}
   914    	}
   915 
   916 /**
   917  *
   918  * Used to change the value of MaxPolyphonyL()
   919  */ 	
   920 void CMidiClientUtility::CBody::SetMaxPolyphonyL(TInt aMaxNotes)
   921 	{
   922 	User::LeaveIfError(iMidiControllerCommands.SetMaxPolyphony(aMaxNotes));
   923 	}
   924 
   925 TInt CMidiClientUtility::CBody::GetRepeats()
   926 	{
   927 	TInt numRepeats = 0;
   928 	iMidiControllerCommands.GetRepeats(numRepeats);
   929 	return numRepeats;
   930 	}
   931 
   932 void CMidiClientUtility::CBody::LoadCustomBankDataL(const TDesC8& aBankData,TInt& aBankId)
   933 	{
   934 	User::LeaveIfError(iMidiControllerCommands.LoadCustomBankData(aBankData, aBankId));
   935 	}
   936 
   937 void CMidiClientUtility::CBody::LoadCustomInstrumentDataL(const TDesC8& aInstrumentData, TInt aBankDataId, TInt aInstrumentDataId, TInt aMemoryBankId, TInt aMemoryInstrumentId)
   938 	{
   939 	if((aInstrumentDataId >= KMinInstrumentId && aInstrumentDataId <= KMaxInstrumentId) 
   940 	&& (aMemoryInstrumentId >= KMinInstrumentId && aMemoryInstrumentId <= KMaxInstrumentId))
   941 		{
   942 		User::LeaveIfError(iMidiControllerCommands.LoadCustomInstrumentData(aInstrumentData, aBankDataId, aInstrumentDataId, aMemoryBankId, aMemoryInstrumentId));
   943 		}
   944 	else
   945 		{
   946 		User::Leave(KErrArgument);
   947 		}
   948 	}
   949 
   950 void CMidiClientUtility::CBody::SetBankL(TBool aCustom)
   951 	{
   952 	User::LeaveIfError(iMidiControllerCommands.SetBank(aCustom));
   953 	}
   954 
   955 TBool CMidiClientUtility::CBody::IsTrackMuteL(TInt aTrack) const
   956 	{
   957 	TBool mute;
   958 	User::LeaveIfError(iMidiControllerCommands.IsTrackMute(aTrack, mute));
   959 	return mute;
   960 	}
   961 
   962 TBool CMidiClientUtility::CBody::IsChannelMuteL(TInt aChannel) const
   963 	{
   964 	TBool mute;
   965 	if (aChannel >= KMinChannel && aChannel <= KMaxChannel)
   966 		{
   967 		User::LeaveIfError(iMidiControllerCommands.IsChannelMute(aChannel, mute));	
   968 		}
   969 	else
   970 		{
   971 		User::Leave(KErrArgument);	
   972 		}
   973 		
   974 	return mute;
   975 	}
   976 
   977 void CMidiClientUtility::CBody::GetInstrumentL(TInt aChannel, TInt& aInstrumentId, TInt& aBankId)
   978 	{
   979 	if (aChannel >= KMinChannel && aChannel <= KMaxChannel)
   980 		{
   981 		User::LeaveIfError(iMidiControllerCommands.GetInstrument(aChannel, aInstrumentId, aBankId));	
   982 		}
   983 	else
   984 		{
   985 		User::Leave(KErrArgument);		
   986 		}
   987 	}
   988 
   989 void CMidiClientUtility::CBody::RepeatTrailingSilenceTimerComplete()
   990 	{
   991 	Play();
   992 	}
   993 
   994 CRepeatTrailingSilenceTimer* CRepeatTrailingSilenceTimer::NewL(MRepeatTrailingSilenceTimerObs& aObs)
   995 	{
   996 	CRepeatTrailingSilenceTimer* s = new(ELeave) CRepeatTrailingSilenceTimer(aObs);
   997 	CleanupStack::PushL(s);
   998 	s->ConstructL();
   999 	CleanupStack::Pop();
  1000 	return s;
  1001 	}
  1002 
  1003 void CRepeatTrailingSilenceTimer::RunL()
  1004 	{
  1005 	iObs.RepeatTrailingSilenceTimerComplete();
  1006 	}
  1007 
  1008 CRepeatTrailingSilenceTimer::CRepeatTrailingSilenceTimer(MRepeatTrailingSilenceTimerObs& aObs) :
  1009 	CTimer(EPriorityHigh),
  1010 	iObs(aObs)
  1011 	{
  1012 	CActiveScheduler::Add(this);
  1013 	}
  1014 
  1015 //
  1016 //
  1017 //
  1018 //
  1019 
  1020 CMidiControllerEventMonitor* CMidiControllerEventMonitor::NewL(MMidiControllerEventMonitorObserver& aMidiObserver, 
  1021 												RMidiControllerCustomCommands& aMidiControllerCustomCommands, const CMidiClientUtility& aParent)
  1022 	{
  1023 	CMidiControllerEventMonitor* self = new(ELeave) CMidiControllerEventMonitor(aMidiObserver, aMidiControllerCustomCommands, aParent);
  1024 	CleanupStack::PushL(self);
  1025 	self->ConstructL();
  1026 	CleanupStack::Pop(self);
  1027 	return self;
  1028 	}
  1029 
  1030 void CMidiControllerEventMonitor::ConstructL()
  1031 	{
  1032 	iMidiEvent = new (ELeave) CMMFMidiEvent();
  1033 	}
  1034 
  1035 CMidiControllerEventMonitor::CMidiControllerEventMonitor(MMidiControllerEventMonitorObserver& aMidiObserver, 
  1036 													   RMidiControllerCustomCommands& aMidiControllerCustomCommands, const CMidiClientUtility& aParent) :
  1037 	CActive(EPriorityStandard),
  1038 	iMidiObserver(aMidiObserver), 
  1039 	iMidiControllerCustomCommands(aMidiControllerCustomCommands),
  1040 	iParent(aParent)
  1041 	{
  1042 	CActiveScheduler::Add(this);
  1043 	}
  1044 
  1045 CMidiControllerEventMonitor::~CMidiControllerEventMonitor()
  1046 	{
  1047 	Cancel();
  1048 	delete iMidiEvent;
  1049 	}
  1050 
  1051 /**
  1052 Start receiving events from the controller.
  1053 
  1054 This can only be called once the controller is open.
  1055 */
  1056 void CMidiControllerEventMonitor::Start()
  1057 	{
  1058 	iMidiControllerCustomCommands.ReceiveEvents(iSizeOfEvent, iStatus);
  1059 	SetActive();
  1060 	}
  1061 
  1062 void CMidiControllerEventMonitor::RunL()
  1063 	{
  1064 	User::LeaveIfError(iStatus.Int());
  1065 
  1066 	// Create a buffer big enough to hold the event, then retrieve it from the server
  1067 	HBufC8* buf = HBufC8::NewLC(iSizeOfEvent());
  1068 	TPtr8 bufPtr = buf->Des();
  1069 	User::LeaveIfError(iMidiControllerCustomCommands.RetrieveEvent(bufPtr));
  1070 
  1071 	// Now internalize a CMMFMidiEvent with the info in the buffer
  1072 	RDesReadStream stream(bufPtr);
  1073 	CleanupClosePushL(stream);
  1074 
  1075 	CMMFMidiEvent* theEvent = new (ELeave) CMMFMidiEvent();
  1076 	
  1077 	CleanupStack::PushL(theEvent);
  1078 	theEvent->InternalizeL(stream);
  1079 	
  1080 	iMidiObserver.HandleMidiEvent(*theEvent);
  1081 	Start();
  1082 
  1083 	CleanupStack::PopAndDestroy(3);//buf, stream, theEvent
  1084 	}
  1085 
  1086 void CMidiControllerEventMonitor::SelfComplete(TInt aError)
  1087 	{
  1088 	Cancel();
  1089 	TRequestStatus *status = &iStatus;
  1090 	if(!IsActive())
  1091 		SetActive();
  1092 	User::RequestComplete(status, aError);
  1093 	}
  1094 
  1095 void CMidiControllerEventMonitor::DoCancel()
  1096 	{
  1097 	iMidiControllerCustomCommands.CancelReceiveEvents();
  1098 	}
  1099 
  1100 TInt CMidiControllerEventMonitor::RunError(TInt aError)
  1101 	{
  1102 	iMidiEvent->iEventType = KMMFErrorCategoryControllerGeneralError;
  1103 	iMidiEvent->iErrorCode = aError;
  1104 	iMidiEvent->iOldState = iParent.State();
  1105 	iMidiEvent->iNewState = iMidiEvent->iOldState;
  1106 
  1107 	iMidiObserver.HandleMidiEvent(*iMidiEvent);
  1108 	Start();
  1109 	return KErrNone;
  1110 	}