mmlibs/mmfw/MIDI/src/midiclientutilitybody.cpp
changeset 0 40261b775718
child 31 ae0addfe117e
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     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    		// FIXME - 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 	}