diff -r 000000000000 -r 40261b775718 mmlibs/mmfw/MIDI/src/midiclientutilitybody.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mmlibs/mmfw/MIDI/src/midiclientutilitybody.cpp Tue Feb 02 01:56:55 2010 +0200 @@ -0,0 +1,1110 @@ +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "midiclientutilitybody.h" + +const TInt KMimeLength = 256; +const TInt KMinChannel = 0; +const TInt KMaxChannel = 15; +const TInt KMinNote = 0; +const TInt KMaxNote = 127; +const TInt KMinNoteOnVelocity = 0; +const TInt KMaxNoteOnVelocity = 127; +const TInt KMinNoteOffVelocity = 0; +const TInt KMaxNoteOffVelocity = 127; +const TInt KMinInstrumentId = 0; +const TInt KMaxInstrumentId = 127; + + +CMidiClientUtility::CBody* CMidiClientUtility::CBody::NewL(CMidiClientUtility* aParent, + MMidiClientUtilityObserver& aObserver, + TInt aPriority, + TInt aPref, + TBool aUseSharedHeap) + { + CBody* self = new(ELeave) CBody(aParent, aObserver, aPriority, aPref); + CleanupStack::PushL(self); + self->ConstructL(aUseSharedHeap); + CleanupStack::Pop(self); + return self; + } + +CMidiClientUtility::CBody::CBody(CMidiClientUtility* aParent, + MMidiClientUtilityObserver& aObserver, + TInt aPriority, + TInt aPref) : + iObserver(aObserver), + iMidiControllerCommands(iController), + iDRMCustomCommands(iController) + + { + iParent = aParent; + iState = EMidiStateClosedDisengaged; + iPrioritySettings.iPriority = aPriority; + iPrioritySettings.iPref = aPref; + iIntervalSec = ETrue; + iStopPosition = TTimeIntervalMicroSeconds(0); + } + +CMidiClientUtility::CBody::~CBody() + { + delete iAddDataSourceSinkAsync; + if (iMidiControllerEventMonitor) + iMidiControllerEventMonitor->Cancel(); + + iController.Close(); + delete iMidiControllerEventMonitor; + delete iMimeType; + delete iRepeatTrailingSilenceTimer; + delete iSource; + } + +void CMidiClientUtility::CBody::ConstructL(TBool aUseSharedHeap) + { + iMidiControllerEventMonitor = CMidiControllerEventMonitor::NewL(*this, iMidiControllerCommands, *iParent); + iMimeType = HBufC8::NewL(KMimeLength); + + RMMFControllerImplInfoArray controllers; + CleanupResetAndDestroyPushL(controllers); + CMMFControllerPluginSelectionParameters* cSelect = CMMFControllerPluginSelectionParameters::NewLC(); + + // Select the media IDs to allow + RArray mediaIds; + CleanupClosePushL(mediaIds); + User::LeaveIfError(mediaIds.Append(KUidMediaTypeMidi)); + cSelect->SetMediaIdsL(mediaIds,CMMFPluginSelectionParameters::EAllowOnlySuppliedMediaIds); + CleanupStack::PopAndDestroy();//mediaIds + cSelect->ListImplementationsL(controllers); + // Open and configure a controller + User::LeaveIfError(DoOpen(controllers, KUidMmfAudioOutput, KNullDesC8, aUseSharedHeap)); + CleanupStack::PopAndDestroy(2);//controllers, cSelect + iRepeatTrailingSilenceTimer = CRepeatTrailingSilenceTimer::NewL(*this); + iAddDataSourceSinkAsync = CMMFAddDataSourceSinkAsync::NewL(*this); + } + +void CMidiClientUtility::CBody::MadssaoAddDataSourceSinkAsyncComplete(TInt aError, const TMMFMessageDestination& aHandle) + { + if (aError == KErrNone) + { + iSourceHandle = aHandle; + } + else + { + iMidiControllerEventMonitor->SelfComplete(aError); + } + } +void CMidiClientUtility::CBody::OpenFile(const TDesC& aFileName) + { + TMMFFileConfig sourceCfg; + sourceCfg().iPath = aFileName; + // Add the data source to the controller. MmcuoStateChanged will be call on completition. + iAddDataSourceSinkAsync->AddDataSource(iController, KUidMmfFileSource, sourceCfg); + } + +void CMidiClientUtility::CBody::OpenFile(RFile& aFile) + { + // Add the data source to the controller. MmcuoStateChanged will be call on completition. + iAddDataSourceSinkAsync->AddFileHandleDataSource(iController, aFile); + } + +void CMidiClientUtility::CBody::OpenFile(const TMMSource& aSource) + { + TRAPD(err, DoOpenFileL(aSource)); + if (err != KErrNone) + { + iMidiControllerEventMonitor->SelfComplete(err); + } + } + + +void CMidiClientUtility::CBody::DoOpenFileL(const TMMSource& aSource) + { + delete iSource; + iSource = NULL; + iSource = CMMFileSourceSink::NewL(KUidMmfFileSource, aSource); + static_cast(iSource)->EvaluateIntentL( aSource.Intent() ); + iAddDataSourceSinkAsync->AddDataSource(iController, + iSource->SourceSinkUid(), + iSource->SourceSinkData()); + } + +void CMidiClientUtility::CBody::OpenDes(const TDesC8& aDescriptor) + { + TMMFDescriptorConfig sourceCfg; + sourceCfg().iDes = (TAny*)&aDescriptor; + sourceCfg().iDesThreadId = RThread().Id(); + // Add the data source to the controller. MmcuoStateChanged will be call on completition. + iAddDataSourceSinkAsync->AddDataSource(iController, KUidMmfDescriptorSource, sourceCfg); + } + +void CMidiClientUtility::CBody::OpenUrl(const TDesC& aUrl,TInt aIapId,const TDesC8& /*aMimeType*/) + { + TRAPD(err, DoOpenUrlL(aUrl, aIapId)); + + if (err != KErrNone) + { + iMidiControllerEventMonitor->SelfComplete(err); + } + + } + +void CMidiClientUtility::CBody::DoOpenUrlL(const TDesC& aUrl,TInt aIapId) + { + CMMFUrlParams* sourceCfg = CMMFUrlParams::NewLC(aUrl, aIapId); + CBufFlat* sourceCfgBuffer = sourceCfg->ExternalizeToCBufFlatLC(); + // Add the data source to the controller. MmcuoStateChanged will be call on completition. + iAddDataSourceSinkAsync->AddDataSource(iController, KUidMmfUrlSource, sourceCfgBuffer->Ptr(0)); + CleanupStack::PopAndDestroy(2, sourceCfg);//sourceCfgBuffer, sourceCfg + } + +void CMidiClientUtility::CBody::Close() + { + iMidiControllerCommands.Close(); + } + +void CMidiClientUtility::CBody::Play() + { + TInt err = iController.Prime(); + if (err==KErrNone) + { + err=iController.Play(); + } + if (err!=KErrNone) + { + iMidiControllerEventMonitor->SelfComplete(err); + } + } + +void CMidiClientUtility::CBody::Stop(const TTimeIntervalMicroSeconds& aFadeOutDuration) + { + iMidiControllerCommands.Stop(aFadeOutDuration); + } + +/** + * + * Returns the current state of the MIDI client utility + * with regard to MIDI resources. + * + * @return "TMidiState" The current state of the utility + * + * @since 7.0s + */ + +TMidiState CMidiClientUtility::CBody::State() const + { + return iState; + } + +void CMidiClientUtility::CBody::PlayNoteL(TInt aChannel,TInt aNote,const TTimeIntervalMicroSeconds& aDuration,TInt aNoteOnVelocity,TInt aNoteOffVelocity) + { + if((aChannel >= KMinChannel && aChannel <= KMaxChannel) + && (aNote >= KMinNote && aNote <= KMaxNote) + && (aNoteOnVelocity >= KMinNoteOnVelocity && aNoteOnVelocity <= KMaxNoteOnVelocity) + && (aNoteOffVelocity >= KMinNoteOffVelocity && aNoteOffVelocity <= KMaxNoteOffVelocity)) + { + User::LeaveIfError(iMidiControllerCommands.PlayNote(aChannel, aNote, aDuration, aNoteOnVelocity, aNoteOffVelocity)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::PlayNoteL(TInt aChannel,TInt aNote, const TTimeIntervalMicroSeconds& aStartTime, const TTimeIntervalMicroSeconds& aDuration, TInt aNoteOnVelocity, TInt aNoteOffVelocity) + { + if((aChannel >= KMinChannel && aChannel <= KMaxChannel) + && (aNote >= KMinNote && aNote <= KMaxNote) + && (aNoteOnVelocity >= KMinNoteOnVelocity && aNoteOnVelocity <= KMaxNoteOnVelocity) + && (aNoteOffVelocity >= KMinNoteOffVelocity && aNoteOffVelocity <= KMaxNoteOffVelocity)) + { + User::LeaveIfError(iMidiControllerCommands.PlayNote(aChannel, aNote, aStartTime, aDuration, aNoteOnVelocity, aNoteOffVelocity)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::StopNotes(TInt aChannel) + { + if(aChannel >= KMinChannel && aChannel <= KMaxChannel) + { + iMidiControllerCommands.StopNotes(aChannel); + } + } + +void CMidiClientUtility::CBody::NoteOnL(TInt aChannel,TInt aNote,TInt aVelocity) + { + if((aChannel >= KMinChannel && aChannel <= KMaxChannel) + && (aNote >= KMinNote && aNote <= KMaxNote) + && (aVelocity >= KMinNoteOnVelocity && aVelocity <= KMaxNoteOnVelocity)) + { + User::LeaveIfError(iMidiControllerCommands.NoteOn(aChannel, aNote, aVelocity)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::NoteOffL(TInt aChannel,TInt aNote,TInt aVelocity) + { + if((aChannel >= KMinChannel && aChannel <= KMaxChannel) + && (aNote >= KMinNote && aNote <= KMaxNote) + && (aVelocity >= KMinNoteOffVelocity && aVelocity <= KMaxNoteOffVelocity)) + { + User::LeaveIfError(iMidiControllerCommands.NoteOff(aChannel, aNote, aVelocity)); + } + else + { + User::Leave(KErrArgument); + } + } + +TInt CMidiClientUtility::CBody::PlaybackRateL() const + { + TInt rate; + User::LeaveIfError(iMidiControllerCommands.PlaybackRate(rate)); + return rate; + } + +void CMidiClientUtility::CBody::SetPlaybackRateL(TInt aRate) + { + User::LeaveIfError(iMidiControllerCommands.SetPlaybackRate(aRate)); + } + +TInt CMidiClientUtility::CBody::MaxPlaybackRateL() const + { + TInt maxRate; + User::LeaveIfError(iMidiControllerCommands.MaxPlaybackRate(maxRate)); + return maxRate; + } + +TInt CMidiClientUtility::CBody::MinPlaybackRateL() const + { + TInt minRate; + User::LeaveIfError(iMidiControllerCommands.MinPlaybackRate(minRate)); + return minRate; + } + + +TInt CMidiClientUtility::CBody::TempoMicroBeatsPerMinuteL() const + { + TInt microBeatsPerMinute; + User::LeaveIfError(iMidiControllerCommands.TempoMicroBeatsPerMinute(microBeatsPerMinute)); + return microBeatsPerMinute; + } + +void CMidiClientUtility::CBody::SetTempoL(TInt aMicroBeatsPerMinute) + { + if(aMicroBeatsPerMinute > 0) + { + User::LeaveIfError(iMidiControllerCommands.SetTempo(aMicroBeatsPerMinute)); + } + else + { + User::Leave(KErrArgument); + } + } + +TInt CMidiClientUtility::CBody::PitchTranspositionCentsL() const + { + TInt cents; + User::LeaveIfError(iMidiControllerCommands.PitchTranspositionCents(cents)); + return cents; + } + +TInt CMidiClientUtility::CBody::SetPitchTranspositionL(TInt aCents) + { + TInt pitchApplied = 0; + //we do not check aCents value - it is expected the controller will report KErrArgument + //if the pitch level is not supported. + User::LeaveIfError(iMidiControllerCommands.SetPitchTransposition(aCents, pitchApplied)); + + return pitchApplied; + } + +TTimeIntervalMicroSeconds CMidiClientUtility::CBody::DurationMicroSecondsL() const + { + TTimeIntervalMicroSeconds duration; + User::LeaveIfError(iController.GetDuration(duration)); + return duration; + } + +TInt64 CMidiClientUtility::CBody::DurationMicroBeatsL() const + { + TInt64 duration; + User::LeaveIfError(iMidiControllerCommands.DurationMicroBeats(duration)); + return duration; + } + +TInt CMidiClientUtility::CBody::NumTracksL() const + { + TInt tracks; + User::LeaveIfError(iMidiControllerCommands.NumTracks(tracks)); + return tracks; + } + +void CMidiClientUtility::CBody::SetTrackMuteL(TInt aTrack, TBool aMuted) const + { + TInt numTracks = NumTracksL(); + if((aTrack >= 0) && (aTrack < numTracks)) + { + User::LeaveIfError(iMidiControllerCommands.SetTrackMute(aTrack, aMuted)); + } + else + { + User::Leave(KErrArgument); + } + } + +const TDesC8& CMidiClientUtility::CBody::MimeTypeL() + { + TPtr8 des = iMimeType->Des(); + User::LeaveIfError(iMidiControllerCommands.MimeType(des)); + return *iMimeType; + } + +TTimeIntervalMicroSeconds CMidiClientUtility::CBody::PositionMicroSecondsL() const + { + TTimeIntervalMicroSeconds position; + User::LeaveIfError(iController.GetPosition(position)); + return position; + } + +void CMidiClientUtility::CBody::SetPositionMicroSecondsL(const TTimeIntervalMicroSeconds& aPosition) + { + TTimeIntervalMicroSeconds maxPosition = DurationMicroSecondsL(); + TTimeIntervalMicroSeconds minPosition(0); + + TTimeIntervalMicroSeconds position = aPosition; + if (aPosition > maxPosition) + { + position = maxPosition; + } + if (aPosition < minPosition) + { + position = minPosition; + } + User::LeaveIfError(iController.SetPosition(position)); + } + +TInt64 CMidiClientUtility::CBody::PositionMicroBeatsL() const + { + TInt64 position; + User::LeaveIfError(iMidiControllerCommands.PositionMicroBeats(position)); + return position; + } + +void CMidiClientUtility::CBody::SetPositionMicroBeatsL(TInt64 aMicroBeats) + { + TInt64 maxPosition = DurationMicroBeatsL(); + TInt64 minPosition(0); + + TInt64 position = aMicroBeats; + if (aMicroBeats > maxPosition) + { + position = maxPosition; + } + if (aMicroBeats < minPosition) + { + position = minPosition; + } + User::LeaveIfError(iMidiControllerCommands.SetPositionMicroBeats(position)); + } + +void CMidiClientUtility::CBody::SetSyncUpdateCallbackIntervalL(const TTimeIntervalMicroSeconds& aMicroSeconds, TInt64 aMicroBeats) + { + + if((aMicroSeconds > TTimeIntervalMicroSeconds(0)) || (aMicroSeconds == TTimeIntervalMicroSeconds(0) && aMicroBeats == 0)) + { + iIntervalSec = ETrue; + } + else + { + if (aMicroBeats > 0) + { + iIntervalSec = EFalse; + } + else + { + User::Leave(KErrArgument); + } + } + + User::LeaveIfError(iMidiControllerCommands.SetSyncUpdateCallbackInterval(aMicroSeconds, aMicroBeats)); + } + +TInt CMidiClientUtility::CBody::SendMessageL(const TDesC8& aMidiMessage) + { + TInt numByteProc; + User::LeaveIfError(iMidiControllerCommands.SendMessage(aMidiMessage, numByteProc)); + return numByteProc; + } + +TInt CMidiClientUtility::CBody::SendMessageL(const TDesC8& aMidiMessage,const TTimeIntervalMicroSeconds& aTime) + { + TInt numByteProc; + User::LeaveIfError(iMidiControllerCommands.SendMessage(aMidiMessage, aTime, numByteProc)); + return numByteProc; + } + +void CMidiClientUtility::CBody::SendMipMessageL(const RArray& aEntry) + { + User::LeaveIfError(iMidiControllerCommands.SendMipMessage(aEntry)); + } + +TInt CMidiClientUtility::CBody::NumberOfBanksL(TBool aCustom) const + { + TInt numBanks; + User::LeaveIfError(iMidiControllerCommands.NumberOfBanks(aCustom, numBanks)); + return numBanks; + } + +TInt CMidiClientUtility::CBody::GetBankIdL(TBool aCustom,TInt aBankIndex) const + { + TInt numBanks = NumberOfBanksL(aCustom); + TInt bankId = 0; + if(aBankIndex >= 0 && aBankIndex < numBanks) + { + User::LeaveIfError(iMidiControllerCommands.GetBankId(aCustom, aBankIndex, bankId)); + } + else + { + User::Leave(KErrArgument); + } + return bankId; + } + +void CMidiClientUtility::CBody::LoadCustomBankL(const TDesC& aFileName,TInt& aBankCollectionIndex) + { + User::LeaveIfError(iMidiControllerCommands.LoadCustomBank(aFileName, aBankCollectionIndex)); + } + +void CMidiClientUtility::CBody::UnloadCustomBankL(TInt aBankCollectionIndex) + { + User::LeaveIfError(iMidiControllerCommands.UnloadCustomBank(aBankCollectionIndex)); + } + +TBool CMidiClientUtility::CBody::CustomBankLoadedL(TInt aBankCollectionIndex) const + { + TBool bankLoaded; + User::LeaveIfError(iMidiControllerCommands.CustomBankLoaded(aBankCollectionIndex, bankLoaded)); + return bankLoaded; + } + +void CMidiClientUtility::CBody::UnloadAllCustomBanksL() + { + User::LeaveIfError(iMidiControllerCommands.UnloadAllCustomBanks()); + } + +TInt CMidiClientUtility::CBody::NumberOfInstrumentsL(TInt aBankId,TBool aCustom) const + { + TInt numInstruments; + User::LeaveIfError(iMidiControllerCommands.NumberOfInstruments(aBankId, aCustom, numInstruments)); + return numInstruments; + } + +TInt CMidiClientUtility::CBody::GetInstrumentIdL(TInt aBankId,TBool aCustom,TInt aInstrumentIndex) const + { + TInt numInstruments = NumberOfInstrumentsL(aBankId, aCustom); + TInt instrumentId = 0; + if(aInstrumentIndex >=0 && aInstrumentIndex < numInstruments) + { + User::LeaveIfError(iMidiControllerCommands.GetInstrumentId(aBankId, aCustom, aInstrumentIndex, instrumentId)); + } + else + { + User::Leave(KErrArgument); + } + return instrumentId; + } + +HBufC* CMidiClientUtility::CBody::InstrumentNameL(TInt aBankId, TBool aCustom, TInt aInstrumentId) const + { + HBufC* instrumentName = NULL; + + if(aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId) + { + instrumentName = iMidiControllerCommands.InstrumentNameL(aBankId, aCustom, aInstrumentId); + } + else + { + User::Leave(KErrArgument); + } + + return instrumentName; + } + +void CMidiClientUtility::CBody::SetInstrumentL(TInt aChannel,TInt aBankId,TInt aInstrumentId) + { + if((aChannel >= KMinChannel && aChannel <= KMaxChannel) + && (aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId)) + { + User::LeaveIfError(iMidiControllerCommands.SetInstrument(aChannel, aBankId, aInstrumentId)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::LoadCustomInstrumentL(const TDesC& aFileName, TInt aFileBankId, TInt aFileInstrumentId, TInt aMemoryBankId, TInt aMemoryInstrumentId) + { + if((aFileInstrumentId >= KMinInstrumentId && aFileInstrumentId <= KMaxInstrumentId) + && (aMemoryInstrumentId >= KMinInstrumentId && aMemoryInstrumentId <= KMaxInstrumentId)) + { + User::LeaveIfError(iMidiControllerCommands.LoadCustomInstrument(aFileName, aFileBankId, aFileInstrumentId, aMemoryBankId, aMemoryInstrumentId)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::UnloadCustomInstrumentL(TInt aCustomBankId,TInt aInstrumentId) + { + if(aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId) + { + User::LeaveIfError(iMidiControllerCommands.UnloadCustomInstrument(aCustomBankId, aInstrumentId)); + } + else + { + User::Leave(KErrArgument); + } + } + +HBufC* CMidiClientUtility::CBody::PercussionKeyNameL(TInt aNote, TInt aBankId, TBool aCustom, TInt aInstrumentId) const + { + HBufC* pKeyName = NULL; + + if((aNote >= KMinNote && aNote <= KMaxNote) + && (aInstrumentId >= KMinInstrumentId && aInstrumentId <= KMaxInstrumentId)) + { + pKeyName = iMidiControllerCommands.PercussionKeyNameL(aNote, aBankId, aCustom, aInstrumentId); + } + else + { + User::Leave(KErrArgument); + } + + return pKeyName; + } + +void CMidiClientUtility::CBody::StopTimeL(TTimeIntervalMicroSeconds& aStopTime) const + { + User::LeaveIfError(iMidiControllerCommands.StopTime(aStopTime)); + } + +void CMidiClientUtility::CBody::SetStopTimeL(const TTimeIntervalMicroSeconds& aStopTime) + { + TTimeIntervalMicroSeconds duration = DurationMicroSecondsL(); + if(aStopTime >= TTimeIntervalMicroSeconds(0) && aStopTime <= duration) + { + User::LeaveIfError(iMidiControllerCommands.SetStopTime(aStopTime)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::SetRepeatsL(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence) + { + if((aRepeatNumberOfTimes >= 0) && (aTrailingSilence >= TTimeIntervalMicroSeconds(0))) + { + User::LeaveIfError(iMidiControllerCommands.SetRepeats(aRepeatNumberOfTimes, aTrailingSilence)); + } + else + { + User::Leave(KErrArgument); + } + } + +TInt CMidiClientUtility::CBody::PolyphonyL() const + { + TInt numNotes; + TInt maxPoly = MaxPolyphonyL(); + User::LeaveIfError(iMidiControllerCommands.Polyphony(numNotes)); + if(maxPoly <= numNotes) + { + return maxPoly; + } + else + { + return numNotes; + } + } + +TInt CMidiClientUtility::CBody::MaxPolyphonyL() const + { + TInt maxNotes; + User::LeaveIfError(iMidiControllerCommands.MaxPolyphony(maxNotes)); + return maxNotes; + } + +TInt CMidiClientUtility::CBody::ChannelsSupportedL() const + { + TInt channels; + User::LeaveIfError(iMidiControllerCommands.ChannelsSupported(channels)); + return channels; + } + +TReal32 CMidiClientUtility::CBody::ChannelVolumeL(TInt aChannel) const + { + TReal32 channelVol; + if(aChannel >= KMinChannel && aChannel <= KMaxChannel) + { + User::LeaveIfError(iMidiControllerCommands.ChannelVolume(aChannel, channelVol)); + } + else + { + User::Leave(KErrArgument); + } + return channelVol; + } + +TReal32 CMidiClientUtility::CBody::MaxChannelVolumeL() const + { + TReal32 maxChanVol; + User::LeaveIfError(iMidiControllerCommands.MaxChannelVolume(maxChanVol)); + return maxChanVol; + } + +void CMidiClientUtility::CBody::SetChannelVolumeL(TInt aChannel,TReal32 aVolume) + { + TReal32 maxChanVol = MaxChannelVolumeL(); + if((aChannel >= KMinChannel && aChannel <= KMaxChannel) && aVolume <= maxChanVol) + { + User::LeaveIfError(iMidiControllerCommands.SetChannelVolume(aChannel, aVolume)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::SetChannelMuteL(TInt aChannel,TBool aMuted) + { + if(aChannel >= KMinChannel && aChannel <= KMaxChannel) + { + User::LeaveIfError(iMidiControllerCommands.SetChannelMute(aChannel, aMuted)); + } + else + { + User::Leave(KErrArgument); + } + } + +TInt CMidiClientUtility::CBody::VolumeL() const + { + TInt vol; + User::LeaveIfError(iMidiControllerCommands.Volume(vol)); + return vol; + } + +TInt CMidiClientUtility::CBody::MaxVolumeL() const + { + TInt maxVol; + User::LeaveIfError(iMidiControllerCommands.MaxVolume(maxVol)); + return maxVol; + } + +void CMidiClientUtility::CBody::SetVolumeL(TInt aVolume) + { + User::LeaveIfError(iMidiControllerCommands.SetVolume(aVolume)); + } + +void CMidiClientUtility::CBody::SetVolumeRampL(const TTimeIntervalMicroSeconds& aRampDuration) + { + User::LeaveIfError(iMidiControllerCommands.SetVolumeRamp(aRampDuration)); + } + + +TInt CMidiClientUtility::CBody::GetBalanceL() const + { + TInt balance; + User::LeaveIfError(iMidiControllerCommands.GetBalance(balance)); + return balance; + } + +void CMidiClientUtility::CBody::SetBalanceL(TInt aBalance) + { + User::LeaveIfError(iMidiControllerCommands.SetBalance(aBalance)); + } + +void CMidiClientUtility::CBody::SetPriorityL(TInt aPriority, TInt aPref) + { + TMMFPrioritySettings priority; + priority.iPriority = aPriority; + priority.iPref = aPref; + + User::LeaveIfError(iController.SetPrioritySettings(priority)); + } + +TInt CMidiClientUtility::CBody::NumberOfMetaDataEntriesL() const + { + TInt numMetaData; + User::LeaveIfError(iController.GetNumberOfMetaDataEntries(numMetaData)); + return numMetaData; + } + +CMMFMetaDataEntry* CMidiClientUtility::CBody::GetMetaDataEntryL(TInt aMetaDataIndex) const + { + CMMFMetaDataEntry* metaDataEntry = iController.GetMetaDataEntryL(aMetaDataIndex); + return metaDataEntry; + } + +void CMidiClientUtility::CBody::CustomCommandSyncL(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) + { + User::LeaveIfError(iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom)); + } + +void CMidiClientUtility::CBody::CustomCommandSyncL(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) + { + User::LeaveIfError(iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2)); + } + +void CMidiClientUtility::CBody::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) + { + iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus); + } + +void CMidiClientUtility::CBody::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) + { + iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus); + } + +MMMFDRMCustomCommand* CMidiClientUtility::CBody::GetDRMCustomCommand() + { + if (iDRMCustomCommands.IsSupported()) + { + return static_cast(&iDRMCustomCommands); + } + return NULL; + } + +TInt CMidiClientUtility::CBody::DoOpen(const RMMFControllerImplInfoArray& aControllers, TUid aSinkUid, const TDesC8& aSinkData, TBool aUseSharedHeap) + { + // Make sure any existing controller is closed. + iMidiControllerEventMonitor->Cancel(); + iController.Close(); + + // Try opening and configuring each controller in turn + TInt error = KErrNotSupported; + TInt index = 0; + while (error) + { + // Break if we're at the end of the array of controllers + if (index >= aControllers.Count()) + break; + + // Open the controller + error = iController.Open(aControllers[index]->Uid(), iPrioritySettings, aUseSharedHeap); + + // If the controller was opened without error, start receiving events from it. + if (error==KErrNone) + { + iMidiControllerEventMonitor->Start(); + } + + // Add the data sink + if (error==KErrNone) + error = iController.AddDataSink(aSinkUid, aSinkData, iSinkHandle); + + // If an error occurred in any of the above, close the controller. + if (error!=KErrNone) + { + iMidiControllerEventMonitor->Cancel(); + iController.Close(); + } + + // increment index + index++; + } + + return error; + } + + void CMidiClientUtility::CBody::HandleMidiEvent(const CMMFMidiEvent& aEvent) + { + if(aEvent.iEventType == KMMFEventCategoryMidiOpenDataSourceComplete || + aEvent.iEventType == KMMFEventCategoryMidiClose || + aEvent.iEventType == KMMFEventCategoryMidiPrime || + aEvent.iEventType == KMMFEventCategoryMidiPlaying || + aEvent.iEventType == KMMFEventCategoryMidiPlaybackIncompatible || + aEvent.iEventType == KMMFEventCategoryMidiPlaybackSilent) + { + iState = aEvent.iNewState; + iObserver.MmcuoStateChanged(aEvent.iOldState, aEvent.iNewState, aEvent.iMicroSeconds, aEvent.iErrorCode); + + if (aEvent.iEventType == KMMFEventCategoryMidiClose) + { + if (iSourceHandle.DestinationHandle()) + { + iController.RemoveDataSource(iSourceHandle); + } + } + } + else if(aEvent.iEventType == KMMFEventCategoryMidiPlayingComplete) + { + iState = aEvent.iNewState; + iObserver.MmcuoStateChanged(aEvent.iOldState, aEvent.iNewState, aEvent.iMicroSeconds, aEvent.iErrorCode); + } + else if(aEvent.iEventType == KMMFEventCategoryMidiSyncUpdate) + { + iObserver.MmcuoSyncUpdate(aEvent.iMicroSeconds, aEvent.iMicroBeats); + } + else if(aEvent.iEventType == KMMFEventCategoryTempoChanged) + { + iObserver.MmcuoTempoChanged(aEvent.iTempoMicroBeats); + } + else if(aEvent.iEventType == KMMFEventCategoryVolumeChanged) + { + iObserver.MmcuoVolumeChanged(aEvent.iChannel, aEvent.iVolumeInDecibels); + } + else if(aEvent.iEventType == KMMFEventCategoryMuteChanged) + { + iObserver.MmcuoMuteChanged(aEvent.iChannel, aEvent.iMute); + } + else if(aEvent.iEventType == KMMFEventCategoryMetaDataEntryFound) + { + iObserver.MmcuoMetaDataEntryFound(aEvent.iMetaDataEntryId, aEvent.iMicroSeconds); + } + else if(aEvent.iEventType == KMMFEventCategoryMipMessageReceived) + { + iObserver.MmcuoMipMessageReceived(aEvent.iMipMessage); + } + else if(aEvent.iEventType == KMMFEventCategoryPolyphonyChanged) + { + iObserver.MmcuoPolyphonyChanged(aEvent.iPolyphony); + } + else if(aEvent.iEventType == KMMFEventCategoryInstrumentChanged) + { + iObserver.MmcuoInstrumentChanged(aEvent.iChannel,aEvent.iBankId,aEvent.iInstrumentId); + } + else if((iState == EMidiStateOpenPlaying) || (iState == EMidiStatePlaybackIncompatible) || + (iState == EMidiStatePlaybackSilent) || (iState == EMidiStateClosedEngaged) || + (iState == EMidiStateOpenEngaged)) + { + iState = aEvent.iNewState; + iObserver.MmcuoStateChanged(aEvent.iOldState, aEvent.iNewState, aEvent.iMicroSeconds, aEvent.iErrorCode); + + } + else if (aEvent.iEventType == KMMFErrorCategoryControllerGeneralError) + { + iObserver.MmcuoStateChanged(iState, iState, TTimeIntervalMicroSeconds(0), aEvent.iErrorCode); + } + else + { + // FIXME - what do we do when we don't understand the error type? + } + } + +/** + * + * Used to change the value of MaxPolyphonyL() + */ +void CMidiClientUtility::CBody::SetMaxPolyphonyL(TInt aMaxNotes) + { + User::LeaveIfError(iMidiControllerCommands.SetMaxPolyphony(aMaxNotes)); + } + +TInt CMidiClientUtility::CBody::GetRepeats() + { + TInt numRepeats = 0; + iMidiControllerCommands.GetRepeats(numRepeats); + return numRepeats; + } + +void CMidiClientUtility::CBody::LoadCustomBankDataL(const TDesC8& aBankData,TInt& aBankId) + { + User::LeaveIfError(iMidiControllerCommands.LoadCustomBankData(aBankData, aBankId)); + } + +void CMidiClientUtility::CBody::LoadCustomInstrumentDataL(const TDesC8& aInstrumentData, TInt aBankDataId, TInt aInstrumentDataId, TInt aMemoryBankId, TInt aMemoryInstrumentId) + { + if((aInstrumentDataId >= KMinInstrumentId && aInstrumentDataId <= KMaxInstrumentId) + && (aMemoryInstrumentId >= KMinInstrumentId && aMemoryInstrumentId <= KMaxInstrumentId)) + { + User::LeaveIfError(iMidiControllerCommands.LoadCustomInstrumentData(aInstrumentData, aBankDataId, aInstrumentDataId, aMemoryBankId, aMemoryInstrumentId)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::SetBankL(TBool aCustom) + { + User::LeaveIfError(iMidiControllerCommands.SetBank(aCustom)); + } + +TBool CMidiClientUtility::CBody::IsTrackMuteL(TInt aTrack) const + { + TBool mute; + User::LeaveIfError(iMidiControllerCommands.IsTrackMute(aTrack, mute)); + return mute; + } + +TBool CMidiClientUtility::CBody::IsChannelMuteL(TInt aChannel) const + { + TBool mute; + if (aChannel >= KMinChannel && aChannel <= KMaxChannel) + { + User::LeaveIfError(iMidiControllerCommands.IsChannelMute(aChannel, mute)); + } + else + { + User::Leave(KErrArgument); + } + + return mute; + } + +void CMidiClientUtility::CBody::GetInstrumentL(TInt aChannel, TInt& aInstrumentId, TInt& aBankId) + { + if (aChannel >= KMinChannel && aChannel <= KMaxChannel) + { + User::LeaveIfError(iMidiControllerCommands.GetInstrument(aChannel, aInstrumentId, aBankId)); + } + else + { + User::Leave(KErrArgument); + } + } + +void CMidiClientUtility::CBody::RepeatTrailingSilenceTimerComplete() + { + Play(); + } + +CRepeatTrailingSilenceTimer* CRepeatTrailingSilenceTimer::NewL(MRepeatTrailingSilenceTimerObs& aObs) + { + CRepeatTrailingSilenceTimer* s = new(ELeave) CRepeatTrailingSilenceTimer(aObs); + CleanupStack::PushL(s); + s->ConstructL(); + CleanupStack::Pop(); + return s; + } + +void CRepeatTrailingSilenceTimer::RunL() + { + iObs.RepeatTrailingSilenceTimerComplete(); + } + +CRepeatTrailingSilenceTimer::CRepeatTrailingSilenceTimer(MRepeatTrailingSilenceTimerObs& aObs) : + CTimer(EPriorityHigh), + iObs(aObs) + { + CActiveScheduler::Add(this); + } + +// +// +// +// + +CMidiControllerEventMonitor* CMidiControllerEventMonitor::NewL(MMidiControllerEventMonitorObserver& aMidiObserver, + RMidiControllerCustomCommands& aMidiControllerCustomCommands, const CMidiClientUtility& aParent) + { + CMidiControllerEventMonitor* self = new(ELeave) CMidiControllerEventMonitor(aMidiObserver, aMidiControllerCustomCommands, aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CMidiControllerEventMonitor::ConstructL() + { + iMidiEvent = new (ELeave) CMMFMidiEvent(); + } + +CMidiControllerEventMonitor::CMidiControllerEventMonitor(MMidiControllerEventMonitorObserver& aMidiObserver, + RMidiControllerCustomCommands& aMidiControllerCustomCommands, const CMidiClientUtility& aParent) : + CActive(EPriorityStandard), + iMidiObserver(aMidiObserver), + iMidiControllerCustomCommands(aMidiControllerCustomCommands), + iParent(aParent) + { + CActiveScheduler::Add(this); + } + +CMidiControllerEventMonitor::~CMidiControllerEventMonitor() + { + Cancel(); + delete iMidiEvent; + } + +/** +Start receiving events from the controller. + +This can only be called once the controller is open. +*/ +void CMidiControllerEventMonitor::Start() + { + iMidiControllerCustomCommands.ReceiveEvents(iSizeOfEvent, iStatus); + SetActive(); + } + +void CMidiControllerEventMonitor::RunL() + { + User::LeaveIfError(iStatus.Int()); + + // Create a buffer big enough to hold the event, then retrieve it from the server + HBufC8* buf = HBufC8::NewLC(iSizeOfEvent()); + TPtr8 bufPtr = buf->Des(); + User::LeaveIfError(iMidiControllerCustomCommands.RetrieveEvent(bufPtr)); + + // Now internalize a CMMFMidiEvent with the info in the buffer + RDesReadStream stream(bufPtr); + CleanupClosePushL(stream); + + CMMFMidiEvent* theEvent = new (ELeave) CMMFMidiEvent(); + + CleanupStack::PushL(theEvent); + theEvent->InternalizeL(stream); + + iMidiObserver.HandleMidiEvent(*theEvent); + Start(); + + CleanupStack::PopAndDestroy(3);//buf, stream, theEvent + } + +void CMidiControllerEventMonitor::SelfComplete(TInt aError) + { + Cancel(); + TRequestStatus *status = &iStatus; + if(!IsActive()) + SetActive(); + User::RequestComplete(status, aError); + } + +void CMidiControllerEventMonitor::DoCancel() + { + iMidiControllerCustomCommands.CancelReceiveEvents(); + } + +TInt CMidiControllerEventMonitor::RunError(TInt aError) + { + iMidiEvent->iEventType = KMMFErrorCategoryControllerGeneralError; + iMidiEvent->iErrorCode = aError; + iMidiEvent->iOldState = iParent.State(); + iMidiEvent->iNewState = iMidiEvent->iOldState; + + iMidiObserver.HandleMidiEvent(*iMidiEvent); + Start(); + return KErrNone; + }