javauis/mmapi_qt/baseline/src/cmmamidicontrol.cpp
branchRCL_3
changeset 24 0fd27995241b
child 26 dc7c549001d5
equal deleted inserted replaced
20:f9bb0fca356a 24:0fd27995241b
       
     1 /*
       
     2 * Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class is a MIDIControl.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 //  INCLUDE FILES
       
    20 #include <logger.h>
       
    21 #include <e32math.h>
       
    22 
       
    23 #include "cmmamidicontrol.h"
       
    24 #include "cmmamidiplayer.h"
       
    25 
       
    26 namespace
       
    27 {
       
    28 const TReal KMMAMIDIVolumeConversionConstant = 40;
       
    29 const TReal KMMADecibelToMidiVolumeConversionPowerBase = 10;
       
    30 //const TTimeIntervalMicroSeconds32 KMMAMIDIVolumeChangeTimeout = 2000000;
       
    31 const TInt KMMAMIDIVolumeChangeTimeout = 2000000;
       
    32 const TReal KMMAMIDIMinimumVolumeDecibels = -130;
       
    33 // For channel volume change message:
       
    34 const TUint8 KMIDIControlChangeEvent = 0xB0;
       
    35 const TUint8 KMIDIControlMainVolume = 0x07;
       
    36 }
       
    37 
       
    38 CMMAMIDIControl* CMMAMIDIControl::NewL(CMMAMIDIPlayer* aPlayer)
       
    39 {
       
    40     CMMAMIDIControl* self = new(ELeave)CMMAMIDIControl(aPlayer);
       
    41     CleanupStack::PushL(self);
       
    42     self->ConstructL();
       
    43     CleanupStack::Pop();
       
    44     return self;
       
    45 }
       
    46 
       
    47 CMMAMIDIControl::CMMAMIDIControl(CMMAMIDIPlayer* aPlayer)
       
    48 {
       
    49     LOG( EJavaMMAPI, EInfo, "MMA:CMMAMIDIControl::CMMAMIDIControl");
       
    50     iPlayer = aPlayer;
       
    51 }
       
    52 
       
    53 CMMAMIDIControl::~CMMAMIDIControl()
       
    54 {
       
    55     LOG( EJavaMMAPI, EInfo, "MMA:CMMAMIDIControl::~CMMAMIDIControl +");
       
    56     delete iVolumeEventWait;
       
    57     LOG( EJavaMMAPI, EInfo, "MMA:CMMAMIDIControl::~CMMAMIDIControl -");
       
    58 }
       
    59 
       
    60 void CMMAMIDIControl::ConstructL()
       
    61 {
       
    62     LOG( EJavaMMAPI, EInfo, "MMA:CMMAMIDIControl::ConstructL +");
       
    63     iVolumeEventWait = CChannelVolumeEventWait::NewL();
       
    64     iPlayer->addObserverL(this);
       
    65     LOG( EJavaMMAPI, EInfo, "MMA:CMMAMIDIControl::ConstructL -");
       
    66 }
       
    67 
       
    68 const TDesC& CMMAMIDIControl::ClassName() const
       
    69 {
       
    70     LOG( EJavaMMAPI, EInfo, "MMA:CMMAMIDIControl::ClassName");
       
    71     return KMIDIControlName;
       
    72 }
       
    73 
       
    74 TInt CMMAMIDIControl::ChannelVolumeL(TInt aChannel)
       
    75 {
       
    76     LOG1( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: ChannelVolumeL + aChannel=%d", aChannel);
       
    77 
       
    78     CMidiClientUtility* midi = iPlayer->MidiClient();
       
    79 
       
    80     // If engine is not processing events, current
       
    81     // volume cannot be known for sure.
       
    82     TMidiState engineState = midi->State();
       
    83 #ifdef RD_JAVA_TMIDISTATECHANGE
       
    84     if ((engineState == EMidiStateClosedDisengaged) ||
       
    85             (engineState == EMidiStateOpenDisengaged))
       
    86 #else
       
    87     if ((engineState == EClosedDisengaged) ||
       
    88             (engineState == EOpenDisengaged))
       
    89 #endif
       
    90     {
       
    91         return KErrNotFound;
       
    92     }
       
    93 
       
    94     // This calculation might be slow on hardware, since
       
    95     // following equation must be calculated using TReals:
       
    96     //
       
    97     // p1 = 10^(dB/40) * p0, where:
       
    98     // p1 is target midi volume,
       
    99     // p0 is reference value (maximum midi volume, 127)
       
   100     // dB is volume value in Decibels from MidiClientUtility
       
   101 
       
   102     TReal32 volume = midi->ChannelVolumeL(aChannel);
       
   103     if (volume < KMMAMIDIMinimumVolumeDecibels)
       
   104     {
       
   105         volume = KMMAMIDIMinimumVolumeDecibels;
       
   106     }
       
   107     TReal exponent = volume / KMMAMIDIVolumeConversionConstant;
       
   108     TReal targetVal = 0;
       
   109 
       
   110     // calculate midi volume value
       
   111     User::LeaveIfError(
       
   112         Math::Pow(
       
   113             targetVal,
       
   114             KMMADecibelToMidiVolumeConversionPowerBase,
       
   115             exponent));
       
   116 
       
   117     // multiply by reference value
       
   118     targetVal *= KMAXVolume;
       
   119 
       
   120     // round value to zero decimals
       
   121     User::LeaveIfError(Math::Round(targetVal, targetVal, 0));
       
   122 
       
   123     // clamp to bounds
       
   124     TInt retVal = (int) targetVal;
       
   125     if (retVal < 0)
       
   126     {
       
   127         retVal  = 0;
       
   128     }
       
   129     else if (retVal > KMAXVolume)
       
   130     {
       
   131         retVal = KMAXVolume;
       
   132     }
       
   133 
       
   134     LOG1( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: ChannelVolumeL - retVal=%d", retVal);
       
   135     return retVal;
       
   136 }
       
   137 
       
   138 void CMMAMIDIControl::SetChannelVolumeL(TInt aChannel, TInt aVolume)
       
   139 {
       
   140     LOG2( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SetChannelVolumeL + aChannel=%d aVolume=%d", aChannel, aVolume);
       
   141 
       
   142     CMidiClientUtility* midi = iPlayer->MidiClient();
       
   143 
       
   144     // Change is done with shortMidiEvent so midi volume -> decibel
       
   145     // calculation is avoided (would be needed for midi client api
       
   146     // SetChannelVolumeL method)
       
   147 
       
   148     TBuf8<3> volumeChangeMessage;
       
   149     // range is checked before
       
   150     TUint8 channel = (KMIDIControlChangeEvent | (TUint8)aChannel);
       
   151     volumeChangeMessage.Append(channel);
       
   152     volumeChangeMessage.Append(KMIDIControlMainVolume);
       
   153     volumeChangeMessage.Append((TUint8)aVolume);
       
   154     SendMIDIEventL(&volumeChangeMessage);
       
   155 
       
   156     TMidiState engineState = midi->State();
       
   157 
       
   158     // If engine is not processing, we do not have to
       
   159     // wait until change is done.
       
   160 #ifdef RD_JAVA_TMIDISTATECHANGE
       
   161     if (!((engineState == EMidiStateClosedDisengaged) ||
       
   162             (engineState == EMidiStateOpenDisengaged)))
       
   163 #else
       
   164     if (!((engineState == EClosedDisengaged) ||
       
   165             (engineState == EOpenDisengaged)))
       
   166 #endif
       
   167     {
       
   168         LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SetChannelVolumeL: ExecuteL ->");
       
   169         iVolumeEventWait->StartWait(aChannel);
       
   170         LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SetChannelVolumeL: ExecuteL <-");
       
   171     }
       
   172     LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SetChannelVolumeL -");
       
   173 }
       
   174 
       
   175 void CMMAMIDIControl::SetProgramL(TInt aChannel,
       
   176                                   TInt aBank,
       
   177                                   TInt aProgram)
       
   178 {
       
   179     CMidiClientUtility* midi = iPlayer->MidiClient();
       
   180 
       
   181     // Program means instrument.
       
   182     midi->SetInstrumentL(aChannel, aBank, aProgram);
       
   183 }
       
   184 
       
   185 TInt CMMAMIDIControl::SendMIDIEventL(const TDesC8* aData)
       
   186 {
       
   187     LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SendMIDIEventL +");
       
   188     CMidiClientUtility* midi = iPlayer->MidiClient();
       
   189 
       
   190     // SendMessageL only processes first message in the descriptor,
       
   191     // so we need to send blocks of data as many times as needed.
       
   192 
       
   193     TInt dataLength = aData->Length();
       
   194     TInt dataSent = 0;
       
   195     while (dataSent < dataLength)
       
   196     {
       
   197         // Delegate event directly to the native implementation
       
   198         // which checks the validity.
       
   199         TPtrC8 nextBlock = aData->Right(dataLength - dataSent);
       
   200         dataSent += midi->SendMessageL(nextBlock);
       
   201     }
       
   202     LOG1( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SendMIDIEventL: sent %d bytes", dataSent);
       
   203     LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: SendMIDIEventL -");
       
   204     return dataSent;
       
   205 }
       
   206 
       
   207 TInt CMMAMIDIControl::ReInitializeMidiL(const TDesC8* aData)
       
   208 {
       
   209     LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: ReInitializeMidiL + ");
       
   210     iPlayer->ReInitializeMidiEngineL(aData);
       
   211     LOG( EJavaMMAPI, EInfo, "MMA: CMMAMIDIControl: ReInitializeMidiL - ");
       
   212     return KErrNone;
       
   213 }
       
   214 
       
   215 void CMMAMIDIControl::MmcuoStateChanged(TMidiState /*aOldState*/,
       
   216                                         TMidiState /*aNewState*/,
       
   217                                         const TTimeIntervalMicroSeconds& /*aTime*/,
       
   218                                         TInt /*aError*/)
       
   219 {
       
   220 }
       
   221 
       
   222 void CMMAMIDIControl::MmcuoTempoChanged(TInt /*aMicroBeatsPerMinute*/)
       
   223 {
       
   224 }
       
   225 
       
   226 void CMMAMIDIControl::MmcuoVolumeChanged(TInt aChannel, TReal32 /*aVolumeInDecibels*/)
       
   227 {
       
   228     LOG1( EJavaMMAPI, EInfo, "CMMAMIDIControl:: MmcuoVolumeChanged + aChannel=%d", aChannel);
       
   229     if (iVolumeEventWait)
       
   230     {
       
   231         iVolumeEventWait->HandleVolumeChangedEvent(aChannel);
       
   232     }
       
   233     LOG( EJavaMMAPI, EInfo, "CMMAMIDIControl:: MmcuoVolumeChanged -");
       
   234 }
       
   235 
       
   236 void CMMAMIDIControl::MmcuoMuteChanged(TInt /*aChannel*/,TBool /*aMuted*/)
       
   237 {
       
   238 }
       
   239 
       
   240 void CMMAMIDIControl::MmcuoSyncUpdate(const TTimeIntervalMicroSeconds& /*aMicroSeconds*/,TInt64 /*aMicroBeats*/)
       
   241 {
       
   242 }
       
   243 
       
   244 void CMMAMIDIControl::MmcuoMetaDataEntryFound(const TInt /*aMetaDataEntryId*/,const TTimeIntervalMicroSeconds& /*aPosition*/)
       
   245 {
       
   246 }
       
   247 
       
   248 void CMMAMIDIControl::MmcuoMipMessageReceived(const RArray<TMipMessageEntry>& /*aMessage*/)
       
   249 {
       
   250 }
       
   251 
       
   252 void CMMAMIDIControl::MmcuoPolyphonyChanged(TInt /*aNewPolyphony*/)
       
   253 {
       
   254 }
       
   255 
       
   256 void CMMAMIDIControl::MmcuoInstrumentChanged(TInt /*aChannel*/,TInt /*aBankId*/,TInt /*aInstrumentId*/)
       
   257 {
       
   258 }
       
   259 
       
   260 CMMAMIDIControl::CChannelVolumeEventWait* CMMAMIDIControl::CChannelVolumeEventWait::NewL()
       
   261 {
       
   262     LOG( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::NewL");
       
   263     CChannelVolumeEventWait* self = new(ELeave) CChannelVolumeEventWait();
       
   264     CleanupStack::PushL(self);
       
   265     self->ConstructL();
       
   266     CleanupStack::Pop();
       
   267     return self;
       
   268 }
       
   269 
       
   270 void CMMAMIDIControl::CChannelVolumeEventWait::ConstructL()
       
   271 {
       
   272     iWait = new(ELeave) CActiveSchedulerWait();
       
   273     iTimer = CTimeOutTimer::NewL(CActive::EPriorityStandard, *this);
       
   274 }
       
   275 
       
   276 CMMAMIDIControl::CChannelVolumeEventWait::CChannelVolumeEventWait()
       
   277 {
       
   278 }
       
   279 
       
   280 CMMAMIDIControl::CChannelVolumeEventWait::~CChannelVolumeEventWait()
       
   281 {
       
   282     delete iTimer;
       
   283     delete iWait;
       
   284 }
       
   285 
       
   286 void CMMAMIDIControl::CChannelVolumeEventWait::TimerExpired()
       
   287 {
       
   288     LOG( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::TimerExpired +");
       
   289     if (iWait->IsStarted())
       
   290     {
       
   291         LOG( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::TimerExpired - cancelling wait");
       
   292         iWait->AsyncStop();
       
   293     }
       
   294     LOG( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::TimerExpired -");
       
   295 }
       
   296 
       
   297 void CMMAMIDIControl::CChannelVolumeEventWait::StartWait(TInt aChannel)
       
   298 {
       
   299     LOG1( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::StartWait aChannel=%d", aChannel);
       
   300     iChannel = aChannel;
       
   301 
       
   302     if (!iWait->IsStarted())
       
   303     {
       
   304         iTimer->After(KMMAMIDIVolumeChangeTimeout);
       
   305         iWait->Start();
       
   306     }
       
   307 }
       
   308 
       
   309 void CMMAMIDIControl::CChannelVolumeEventWait::StopWait()
       
   310 {
       
   311     LOG( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::StopWait");
       
   312     if (iWait->IsStarted())
       
   313     {
       
   314         iTimer->Cancel();
       
   315         iWait->AsyncStop();
       
   316     }
       
   317 }
       
   318 
       
   319 void CMMAMIDIControl::CChannelVolumeEventWait::HandleVolumeChangedEvent(TInt aChannel)
       
   320 {
       
   321     LOG1( EJavaMMAPI, EInfo, "CMMAMIDIControl::CChannelVolumeEventWait::HandleVolumeChangedEvent aChannel=%d", aChannel);
       
   322     if (iChannel == aChannel)
       
   323     {
       
   324         StopWait();
       
   325     }
       
   326 }
       
   327 
       
   328 //  END OF FILE