mmserv/voipaudioservices/VoIPServer/src/VoIPDownlinkThread.cpp
changeset 0 71ca22bcf22a
child 9 f5c5c82a163e
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2  * Copyright (c) 2007-2009 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:  VoIP Audio Services
       
    15  *               Implements downlink thread object.
       
    16  *
       
    17  */
       
    18 
       
    19 #include <AudioOutput.h>
       
    20 #include <IlbcDecoderIntfc.h>
       
    21 #include <G711DecoderIntfc.h>
       
    22 #include <G729DecoderIntfc.h>
       
    23 #include <ErrorConcealmentIntfc.h>
       
    24 #include <voipdownlinkstream.h>
       
    25 #include "debugtracemacros.h"
       
    26 #include "VoIPSharedData.h"
       
    27 #include "VoIPServerThread.h"
       
    28 
       
    29 // -----------------------------------------------------------------------------
       
    30 // CVoIPDownlinkThread::CVoIPDownlinkThread
       
    31 // Standard Constructor
       
    32 // -----------------------------------------------------------------------------
       
    33 //
       
    34 CVoIPDownlinkThread::CVoIPDownlinkThread(TSharedData& aData) :
       
    35     iShared(aData)
       
    36     {
       
    37     }
       
    38 
       
    39 // -----------------------------------------------------------------------------
       
    40 // CVoIPDownlinkThread::~CVoIPDownlinkThread
       
    41 // Standard Constructor
       
    42 // -----------------------------------------------------------------------------
       
    43 //
       
    44 CVoIPDownlinkThread::~CVoIPDownlinkThread()
       
    45     {
       
    46     TRACE_PRN_FN_ENT;
       
    47 
       
    48     Stop();
       
    49 
       
    50     delete iJitterBuffer;
       
    51     delete iAddJBuffer;
       
    52     delete iGetJBuffer;
       
    53 
       
    54     delete iAudioOutput;
       
    55     delete iErrConcealmentIntfc;
       
    56     delete iG711DecoderIntfc;
       
    57     delete iG729DecoderIntfc;
       
    58     delete iIlbcDecoderIntfc;
       
    59 
       
    60     TRACE_PRN_FN_EXT;
       
    61     }
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CVoIPDownlinkThread::NewL
       
    65 // Symbian two-phase constructor
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 CVoIPDownlinkThread* CVoIPDownlinkThread::NewL(TSharedData& aData)
       
    69     {
       
    70     CVoIPDownlinkThread* self = new (ELeave) CVoIPDownlinkThread(aData);
       
    71     CleanupStack::PushL(self);
       
    72     self->ConstructL();
       
    73     CleanupStack::Pop(self);
       
    74     return self;
       
    75     }
       
    76 
       
    77 // -----------------------------------------------------------------------------
       
    78 // CVoIPDownlinkThread::ConstructL
       
    79 // Part two of Symbian two phase construction
       
    80 // -----------------------------------------------------------------------------
       
    81 //
       
    82 void CVoIPDownlinkThread::ConstructL()
       
    83     {
       
    84     TRACE_PRN_FN_ENT;
       
    85 
       
    86     InitThreadL();
       
    87     iCodecID = iShared.iCodecSettings.iFourCC;
       
    88     InitMsgQueuesL(KDnLinkQueue, KDnLinkThreadComQueue);
       
    89 
       
    90     iShared.iMutex.Wait();
       
    91     TRAPD(err, InitDevSoundL(EMMFStatePlaying, iShared.iPriority,
       
    92             iShared.iPreference));
       
    93     iShared.iMutex.Signal();
       
    94 
       
    95     if (err != KErrNone)
       
    96         {
       
    97         SendCmd(ECmdDnLinkError, err);
       
    98         }
       
    99     iMaxBufLen = DetermineMaxBufferLen(iShared.iCodecSettings.iG711FrameRate);
       
   100 
       
   101     // Client must set these before querying!
       
   102     iG711CodecMode = CVoIPFormatIntfc::EG711ALaw;
       
   103     iILBCCodecMode = CVoIPFormatIntfc::EiLBC20mSecFrame;
       
   104 
       
   105     TRACE_PRN_FN_EXT;
       
   106     }
       
   107 
       
   108 // -----------------------------------------------------------------------------
       
   109 // CVoIPDownlinkThread::ThreadFunction
       
   110 // Thread Startup function
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 TInt CVoIPDownlinkThread::ThreadFunction(TAny* aData)
       
   114     {
       
   115     // get a pointer to the shared data object
       
   116     TSharedData& shared = *((TSharedData*) aData);
       
   117 
       
   118     // we can set the sync flag here
       
   119     shared.iMutex.Wait();
       
   120 
       
   121     // create a cleanup stack
       
   122     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   123 
       
   124     if (!cleanupStack)
       
   125         {
       
   126         return KErrNoMemory;
       
   127         }
       
   128 
       
   129     CVoIPDownlinkThread* thread = 0;
       
   130     TRAPD(err, thread = CVoIPDownlinkThread::NewL(shared));
       
   131     if (err != KErrNone)
       
   132         {
       
   133         return err;
       
   134         }
       
   135 
       
   136     shared.iMutex.Signal();
       
   137 
       
   138     // if we're still here, active scheduler has been constructed
       
   139     // start wait loop which runs until it's time to end the thread
       
   140     CActiveScheduler::Start();
       
   141 
       
   142     // Termination cleanup
       
   143     delete thread;
       
   144     delete cleanupStack;
       
   145 
       
   146     TRACE_PRN_N(_L("VoIP Downlink Thread CLOSED"));
       
   147     return KErrNone;
       
   148     }
       
   149 
       
   150 // -----------------------------------------------------------------------------
       
   151 // CVoIPDownlinkThread::Start
       
   152 //
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void CVoIPDownlinkThread::Start()
       
   156     {
       
   157     TRACE_PRN_FN_ENT;
       
   158 
       
   159     TInt err = KErrNotReady;
       
   160 
       
   161     if (iStatus == EReady)
       
   162         {
       
   163         TRAP(err, iDevSound->PlayInitL());
       
   164         TRACE_PRN_IF_ERR(err);
       
   165 
       
   166 #ifdef _DEBUG
       
   167         iSamplesPlayedCount = 0;
       
   168 #endif
       
   169         if (err != KErrNone)
       
   170             {
       
   171             SendCmd(ECmdDnLinkError, err);
       
   172             iStatus = EReady;
       
   173             }
       
   174         else
       
   175             {
       
   176             if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
   177                 {
       
   178                 iJitterBuffer->Play();
       
   179                 }
       
   180             }
       
   181         }
       
   182 
       
   183     TRACE_PRN_FN_EXT;
       
   184     }
       
   185 
       
   186 // -----------------------------------------------------------------------------
       
   187 // CVoIPDownlinkThread::Stop
       
   188 //
       
   189 // -----------------------------------------------------------------------------
       
   190 //
       
   191 void CVoIPDownlinkThread::Stop()
       
   192     {
       
   193     TRACE_PRN_FN_ENT;
       
   194 
       
   195     if (iStatus == EStreaming)
       
   196         {
       
   197         if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
   198             {
       
   199             iJitterBuffer->Stop();
       
   200             }
       
   201 
       
   202         iDevSound->Stop();
       
   203         iStatus = EReady;
       
   204         }
       
   205 
       
   206     TRACE_PRN_FN_EXT;
       
   207     }
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CVoIPDownlinkThread::InitializeComplete
       
   211 // A callback from the DevSound indicating completion of the initialization.
       
   212 // It will send config data to the D/S and configure the encoder via CI.
       
   213 // If everything goes well, the state of the thread is set EReady.
       
   214 // The initialization completion message is sent back to the main thread.
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 void CVoIPDownlinkThread::InitializeComplete(TInt aError)
       
   218     {
       
   219     TRACE_PRN_FN_ENT;
       
   220 
       
   221     TInt err = aError;
       
   222 
       
   223     if (iDevSound && err == KErrNone)
       
   224         {
       
   225         TMMFCapabilities conf;
       
   226         conf = iDevSound->Config();
       
   227         conf.iRate = EMMFSampleRate8000Hz;
       
   228         conf.iChannels = EMMFMono;
       
   229         TRAP(err, iDevSound->SetConfigL(conf));
       
   230         if (err == KErrNone)
       
   231             {
       
   232             // We are ready to stream even in case of later CI setting failure
       
   233             iStatus = EReady;
       
   234             TInt vol = iDevSound->MaxVolume();
       
   235             iShared.iMutex.Wait();
       
   236             iShared.iMaxVolume = vol;
       
   237             iShared.iMutex.Signal();
       
   238             }
       
   239 
       
   240         // Init Custom Interface API to the decoder
       
   241         TRAPD(err0, SetCodecCiL());
       
   242         if (err0 != KErrNone)
       
   243             {
       
   244             // DEBUG only
       
   245             // Can ignore error - the decoder is not fully configured but
       
   246             // can still run in the default mode.
       
   247             TRACE_PRN_IF_ERR(err0);
       
   248             }
       
   249         }
       
   250 
       
   251     // Notify the main thread
       
   252     SendCmd(ECmdDownlinkInitComplete, err);
       
   253 
       
   254     TRACE_PRN_IF_ERR(err);
       
   255     TRACE_PRN_FN_EXT;
       
   256     }
       
   257 
       
   258 // -----------------------------------------------------------------------------
       
   259 // CVoIPDownlinkThread::BufferToBeFilled
       
   260 // A reference to the buffer delivered from the DevSound is stored locally
       
   261 // for later use. It will be filled with the data passed from the client
       
   262 // when it calls BufferFilled.
       
   263 // -----------------------------------------------------------------------------
       
   264 //
       
   265 void CVoIPDownlinkThread::BufferToBeFilled(CMMFBuffer* aBuffer)
       
   266     {
       
   267     //TRACE_PRN_FN_ENT;
       
   268 
       
   269     // Store pointer to the received buffer
       
   270     iDevSoundBufPtr = static_cast<CMMFDataBuffer*> (aBuffer);
       
   271     iBufLen = iDevSoundBufPtr->RequestSize();
       
   272     TRACE_PRN_N1(_L("VoIP->DNL->BTBF:LEN[%d]"), iBufLen);
       
   273 
       
   274 #ifndef __WINSCW__
       
   275     // The first AMR buffer returns 1 for no data frame.
       
   276     if (iCodecID == KMccFourCCIdAMRNB)
       
   277         {
       
   278         iBufLen = iMaxBufLen;
       
   279         }
       
   280 #else  //__WINSCW__
       
   281     // Don't care about full 4k data buffer in WINS
       
   282     iBufLen = iMaxBufLen;
       
   283 #endif //__WINSCW__
       
   284 
       
   285     // Create or adjust the chunk
       
   286     TInt err = DoChunk(KChunkDNL, iBufLen, iMaxBufLen);
       
   287 
       
   288     if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
   289         {
       
   290         // Note: Do not send ECmdFillBuffer to the client except if error
       
   291         if (err != KErrNone)
       
   292             {
       
   293             Stop();
       
   294             iMsgBuffer.iStatus = err;
       
   295             iMsgBuffer.iRequest = ECmdFillBuffer;
       
   296             iMsgQueue.Send(iMsgBuffer);
       
   297             }
       
   298         else
       
   299             {
       
   300             // If JB below threshold, it will generate and return SID frames.
       
   301             TRAP(err, iGetJBuffer->SetRequestSizeL(iBufLen)); // for CNG
       
   302 
       
   303             // Use current buf to play (if data available)
       
   304             err = iJitterBuffer->FillBuffer(iGetJBuffer);
       
   305             iStatus = EStreaming;
       
   306             }
       
   307         }
       
   308     else // non-JB case
       
   309         {
       
   310         if (err != KErrNone)
       
   311             {
       
   312             Stop();
       
   313             iMsgBuffer.iStatus = err;
       
   314             }
       
   315         else
       
   316             {
       
   317             // Notify client there is buffer ready to be filled
       
   318             iMsgBuffer.iStatus = iChunk.Handle();
       
   319             iMsgBuffer.iInt = iBufLen;
       
   320             iStatus = EStreaming;
       
   321             }
       
   322 
       
   323         iMsgBuffer.iRequest = ECmdFillBuffer;
       
   324         iMsgQueue.Send(iMsgBuffer);
       
   325         }
       
   326 
       
   327     TRACE_PRN_IF_ERR(err);
       
   328     //TRACE_PRN_FN_EXT;
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // CVoIPDownlinkThread::BufferFilled
       
   333 //
       
   334 // -----------------------------------------------------------------------------
       
   335 //
       
   336 void CVoIPDownlinkThread::BufferFilled()
       
   337     {
       
   338     // TODO: Check D/S status to protect from call to PlayData prior to
       
   339     // PlayInitL, the case when D/S is stopped either by the user or due to
       
   340     // an error.
       
   341 
       
   342     TUint seqNum;
       
   343     TBool badFrame = EFalse;
       
   344 
       
   345     iShared.iMutex.Wait();
       
   346     iBufLen = iShared.iBufferSize; //length of data in the buffer
       
   347     seqNum = iShared.iSequenceNum;
       
   348     iShared.iMutex.Signal();
       
   349     TRACE_PRN_N1(_L("VoIP->DNL->BF: LEN[%d]"), iBufLen);
       
   350 
       
   351     if (iBufLen > iMaxBufLen)
       
   352         {
       
   353         iBufLen = iMaxBufLen;
       
   354         badFrame = ETrue;
       
   355         TRACE_PRN_N(_L("VoIP->DNL: BAD FRAME"));
       
   356         }
       
   357 
       
   358     // Copy data over from chunk
       
   359     TPtr8 dataPtr(iChunk.Base(), iBufLen, iMaxBufLen);
       
   360 
       
   361     if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
   362         {
       
   363         if (badFrame)
       
   364             {
       
   365             dataPtr.FillZ(); // JB will throw it away
       
   366             }
       
   367 
       
   368         // Send data to JB. When ready to play JB will call back via EventJB().
       
   369         iAddJBuffer->Data() = dataPtr;
       
   370         iAddJBuffer->SetFrameNumber(seqNum);
       
   371         iJitterBuffer->EmptyBuffer(iAddJBuffer);
       
   372         }
       
   373     else
       
   374         {
       
   375         if (iStatus == EStreaming)
       
   376             {
       
   377             if (badFrame)
       
   378                 {
       
   379                 ConcealErrorForNextBuffer();
       
   380                 }
       
   381 
       
   382             // Fill D/S buffer and send it for playback
       
   383             iDevSoundBufPtr->Data() = dataPtr;
       
   384             iDevSound->PlayData();
       
   385 
       
   386             //TRACE_PRN_N1(_L("SAMPLES-PLAYED [%d]"), iSamplesPlayedCount++);
       
   387             }
       
   388         }
       
   389     }
       
   390 
       
   391 // -----------------------------------------------------------------------------
       
   392 // CVoIPDownlinkThread::PlayError
       
   393 // From MDevSoundObserver
       
   394 // Record error is send to client over comm channel.
       
   395 // The state of recorder is rolled back to EReady.
       
   396 // -----------------------------------------------------------------------------
       
   397 //
       
   398 void CVoIPDownlinkThread::PlayError(TInt aError)
       
   399     {
       
   400     TRACE_PRN_IF_ERR(aError);
       
   401 
       
   402 #ifdef _DEBUG
       
   403     iSamplesPlayedCount = 0;
       
   404 #endif
       
   405     iStatus = EReady;
       
   406     SendCmd(ECmdDnLinkError, aError);
       
   407     }
       
   408 
       
   409 // -----------------------------------------------------------------------------
       
   410 // CVoIPDownlinkThread::SetCodecCiL
       
   411 //
       
   412 // -----------------------------------------------------------------------------
       
   413 //
       
   414 void CVoIPDownlinkThread::SetCodecCiL()
       
   415     {
       
   416     TRACE_PRN_FN_ENT;
       
   417 
       
   418     if (iCodecID == KMccFourCCIdG711 ||
       
   419         iCodecID == KMccFourCCIdG729 ||
       
   420         iCodecID == KMccFourCCIdILBC ||
       
   421         iCodecID == KMccFourCCIdAMRNB)
       
   422         {
       
   423         if (!iErrConcealmentIntfc)
       
   424             {
       
   425             iErrConcealmentIntfc = CErrorConcealmentIntfc::NewL(*iDevSound);
       
   426             }
       
   427         }
       
   428 
       
   429     switch (iCodecID)
       
   430         {
       
   431         case KMccFourCCIdG711:
       
   432             {
       
   433             if (!iG711DecoderIntfc)
       
   434                 {
       
   435                 iG711DecoderIntfc = CG711DecoderIntfc::NewL(*iDevSound);
       
   436                 }
       
   437             break;
       
   438             }
       
   439         case KMccFourCCIdG729:
       
   440             {
       
   441             if (!iG729DecoderIntfc)
       
   442                 {
       
   443                 iG729DecoderIntfc = CG729DecoderIntfc::NewL(*iDevSound);
       
   444                 }
       
   445             break;
       
   446             }
       
   447         case KMccFourCCIdILBC:
       
   448             {
       
   449             if (!iIlbcDecoderIntfc)
       
   450                 {
       
   451                 iIlbcDecoderIntfc = CIlbcDecoderIntfc::NewL(*iDevSound);
       
   452                 }
       
   453             break;
       
   454             }
       
   455         case KMccFourCCIdAMRNB:
       
   456         case KMMFFourCCCodePCM16:
       
   457         default:
       
   458             {
       
   459             break;
       
   460             }
       
   461         }
       
   462 
       
   463     TRACE_PRN_FN_EXT;
       
   464     }
       
   465 
       
   466 // -----------------------------------------------------------------------------
       
   467 // CVoIPDownlinkThread::SetVolume
       
   468 //
       
   469 // -----------------------------------------------------------------------------
       
   470 //
       
   471 void CVoIPDownlinkThread::SetVolume()
       
   472     {
       
   473     iShared.iMutex.Wait();
       
   474     TInt vol = iShared.iInt;
       
   475     iShared.iMutex.Signal();
       
   476     iDevSound->SetVolume(vol);
       
   477     TRACE_PRN_N1(_L("VoIP->DNL: SetVolume [%d]"), vol);
       
   478     }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // CVoIPDownlinkThread::GetVolume
       
   482 //
       
   483 // -----------------------------------------------------------------------------
       
   484 //
       
   485 void CVoIPDownlinkThread::GetVolume()
       
   486     {
       
   487     TInt vol = iDevSound->Volume();
       
   488     iShared.iMutex.Wait();
       
   489     iShared.iInt = vol;
       
   490     iShared.iMutex.Signal();
       
   491     SendCmd(ECmdGetVolumeComplete);
       
   492     }
       
   493 
       
   494 // -----------------------------------------------------------------------------
       
   495 // CVoIPDownlinkThread::SetAudioDeviceL
       
   496 //
       
   497 // -----------------------------------------------------------------------------
       
   498 //
       
   499 void CVoIPDownlinkThread::SetAudioDeviceL()
       
   500     {
       
   501     TRACE_PRN_FN_ENT;
       
   502 
       
   503     iShared.iMutex.Wait();
       
   504     TUint device = iShared.iAudioDevice;
       
   505     iShared.iMutex.Signal();
       
   506 
       
   507     if (!iAudioOutput)
       
   508         {
       
   509         iAudioOutput = CAudioOutput::NewL(*iDevSound);
       
   510         }
       
   511 
       
   512     if (iAudioOutput)
       
   513         {
       
   514         // ENoPreference=0, EAll=1, ENoOutput=2, EPrivate=3, EPublic=4
       
   515         CAudioOutput::TAudioOutputPreference outputDev;
       
   516 
       
   517         if (CVoIPAudioDownlinkStream::TVoIPOutputDevice(device) ==
       
   518                 CVoIPAudioDownlinkStream::EHandset)
       
   519             {
       
   520             outputDev = CAudioOutput::EPrivate;
       
   521             }
       
   522         else if (CVoIPAudioDownlinkStream::TVoIPOutputDevice(device) ==
       
   523                 CVoIPAudioDownlinkStream::ELoudSpeaker)
       
   524             {
       
   525             outputDev = CAudioOutput::EPublic;
       
   526             }
       
   527         else // Use default device routing
       
   528             {
       
   529             outputDev = CAudioOutput::ENoPreference;
       
   530             } //make sure doesn't break loudspeaker audio
       
   531 
       
   532         iAudioOutput->SetAudioOutputL(outputDev);
       
   533         }
       
   534 
       
   535     TRACE_PRN_FN_EXT;
       
   536     }
       
   537 
       
   538 // -----------------------------------------------------------------------------
       
   539 // CVoIPDownlinkThread::GetAudioDeviceL
       
   540 //
       
   541 // -----------------------------------------------------------------------------
       
   542 //
       
   543 void CVoIPDownlinkThread::GetAudioDeviceL()
       
   544     {
       
   545     TRACE_PRN_FN_ENT;
       
   546 
       
   547     if (!iAudioOutput)
       
   548         {
       
   549         iAudioOutput = CAudioOutput::NewL(*iDevSound);
       
   550         }
       
   551 
       
   552     if (iAudioOutput)
       
   553         {
       
   554         CAudioOutput::TAudioOutputPreference outputDev =
       
   555                 iAudioOutput->AudioOutput();
       
   556 
       
   557         CVoIPAudioDownlinkStream::TVoIPOutputDevice device;
       
   558 
       
   559         switch (outputDev)
       
   560             {
       
   561             case (CAudioOutput::ENoPreference):
       
   562             case (CAudioOutput::EAll):
       
   563             case (CAudioOutput::ENoOutput):
       
   564             case (CAudioOutput::EPrivate):
       
   565             default:
       
   566                 device = CVoIPAudioDownlinkStream::EHandset;
       
   567                 break;
       
   568             case (CAudioOutput::EPublic):
       
   569                 device = CVoIPAudioDownlinkStream::ELoudSpeaker;
       
   570                 break;
       
   571             }
       
   572 
       
   573         iShared.iMutex.Wait();
       
   574         iShared.iAudioDevice = TUint(device);
       
   575         iShared.iMutex.Signal();
       
   576         SendCmd(ECmdGetAudioDeviceComplete);
       
   577         }
       
   578 
       
   579     TRACE_PRN_FN_EXT;
       
   580     }
       
   581 
       
   582 // -----------------------------------------------------------------------------
       
   583 // CVoIPDownlinkThread::SetIlbcCodecMode
       
   584 //
       
   585 // -----------------------------------------------------------------------------
       
   586 //
       
   587 void CVoIPDownlinkThread::SetIlbcCodecMode()
       
   588     {
       
   589     TInt err = KErrNotSupported;
       
   590 
       
   591     if (iStatus == EReady)
       
   592         {
       
   593         iShared.iMutex.Wait();
       
   594         iILBCCodecMode = iShared.iCodecSettings.iILBCCodecMode;
       
   595         iShared.iMutex.Signal();
       
   596 
       
   597         if (iIlbcDecoderIntfc && iCodecID == KMccFourCCIdILBC)
       
   598             {
       
   599             if (iILBCCodecMode == CVoIPFormatIntfc::EiLBC20mSecFrame)
       
   600                 {
       
   601                 err = iIlbcDecoderIntfc->SetDecoderMode(
       
   602                         CIlbcDecoderIntfc::E20msFrame);
       
   603                 TRACE_PRN_N(_L("VoIP->DNL iLBC Mode Set: [20ms]"));
       
   604                 }
       
   605             else if (iILBCCodecMode == CVoIPFormatIntfc::EiLBC30mSecFrame)
       
   606                 {
       
   607                 err = iIlbcDecoderIntfc->SetDecoderMode(
       
   608                         CIlbcDecoderIntfc::E30msFrame);
       
   609                 TRACE_PRN_N(_L("VoIP->DNL iLBC Mode Set: [30ms]"));
       
   610                 }
       
   611             }
       
   612         }
       
   613 
       
   614     if (err != KErrNone)
       
   615         {
       
   616         SendCmd(ECmdDnLinkError, err);
       
   617         }
       
   618 
       
   619     TRACE_PRN_IF_ERR(err);
       
   620     }
       
   621 
       
   622 // -----------------------------------------------------------------------------
       
   623 // CVoIPDownlinkThread::GetIlbcCodecMode
       
   624 //
       
   625 // -----------------------------------------------------------------------------
       
   626 //
       
   627 void CVoIPDownlinkThread::GetIlbcCodecMode()
       
   628     {
       
   629     // not available through CIs -> return local value
       
   630     iShared.iMutex.Wait();
       
   631     iShared.iCodecSettings.iILBCCodecMode = iILBCCodecMode;
       
   632     iShared.iMutex.Signal();
       
   633     SendCmd(ECmdGetIlbcCodecModeComplete);
       
   634     }
       
   635 
       
   636 // -----------------------------------------------------------------------------
       
   637 // CVoIPDownlinkThread::SetG711CodecMode
       
   638 //
       
   639 // -----------------------------------------------------------------------------
       
   640 //
       
   641 void CVoIPDownlinkThread::SetG711CodecMode()
       
   642     {
       
   643     TInt err = KErrNotSupported;
       
   644 
       
   645     if (iStatus == EReady)
       
   646         {
       
   647         iShared.iMutex.Wait();
       
   648         iG711CodecMode = iShared.iCodecSettings.iG711CodecMode;
       
   649         iShared.iMutex.Signal();
       
   650 
       
   651         if (iG711DecoderIntfc && iCodecID == KMccFourCCIdG711)
       
   652             {
       
   653             if (iG711CodecMode == CVoIPFormatIntfc::EG711ALaw)
       
   654                 {
       
   655                 err = iG711DecoderIntfc->SetDecoderMode(
       
   656                         CG711DecoderIntfc::EDecALaw);
       
   657                 TRACE_PRN_N(_L("VoIP->DNL G711 Mode Set: [ALaw]"));
       
   658                 }
       
   659             else if (iG711CodecMode == CVoIPFormatIntfc::EG711uLaw)
       
   660                 {
       
   661                 err = iG711DecoderIntfc->SetDecoderMode(
       
   662                         CG711DecoderIntfc::EDecULaw);
       
   663                 TRACE_PRN_N(_L("VoIP->DNL G711 Mode Set: [uLaw]"));
       
   664                 }
       
   665             }
       
   666         }
       
   667 
       
   668     if (err != KErrNone)
       
   669         {
       
   670         SendCmd(ECmdDnLinkError, err);
       
   671         }
       
   672 
       
   673     TRACE_PRN_IF_ERR(err);
       
   674     }
       
   675 
       
   676 // -----------------------------------------------------------------------------
       
   677 // CVoIPDownlinkThread::GetG711CodecMode
       
   678 //
       
   679 // -----------------------------------------------------------------------------
       
   680 //
       
   681 void CVoIPDownlinkThread::GetG711CodecMode()
       
   682     {
       
   683     // not available through CIs -> return local value
       
   684     iShared.iMutex.Wait();
       
   685     iShared.iCodecSettings.iG711CodecMode = iG711CodecMode;
       
   686     iShared.iMutex.Signal();
       
   687     SendCmd(ECmdGetG711CodecModeComplete);
       
   688     }
       
   689 
       
   690 // -----------------------------------------------------------------------------
       
   691 // CVoIPDownlinkThread::FrameModeRqrdForEC
       
   692 //
       
   693 // -----------------------------------------------------------------------------
       
   694 //
       
   695 void CVoIPDownlinkThread::FrameModeRqrdForEC()
       
   696     {
       
   697     TInt err = KErrNotSupported;
       
   698 
       
   699     if (iStatus == EReady)
       
   700         {
       
   701         TBool modeReq = EFalse;
       
   702 
       
   703         if (iErrConcealmentIntfc)
       
   704             {
       
   705             err = iErrConcealmentIntfc->FrameModeRqrdForEC(modeReq);
       
   706             }
       
   707 
       
   708         iShared.iMutex.Wait();
       
   709         iShared.iCodecSettings.iFrameModeReqForEC = modeReq;
       
   710         iShared.iMutex.Signal();
       
   711         }
       
   712 
       
   713     SendCmd(ECmdGetFrameModeReqForECComplete, err);
       
   714     TRACE_PRN_IF_ERR(err);
       
   715     }
       
   716 
       
   717 // -----------------------------------------------------------------------------
       
   718 // CVoIPDownlinkThread::SetFrameMode
       
   719 //
       
   720 // -----------------------------------------------------------------------------
       
   721 //
       
   722 void CVoIPDownlinkThread::SetFrameMode()
       
   723     {
       
   724     TInt err = KErrNotSupported;
       
   725 
       
   726     if (iStatus == EReady)
       
   727         {
       
   728         iShared.iMutex.Wait();
       
   729         iFrameMode = iShared.iCodecSettings.iFrameMode;
       
   730         iShared.iMutex.Signal();
       
   731 
       
   732         if (iErrConcealmentIntfc)
       
   733             {
       
   734             err = iErrConcealmentIntfc->SetFrameMode(iFrameMode);
       
   735             }
       
   736         }
       
   737 
       
   738     if (err != KErrNone)
       
   739         {
       
   740         SendCmd(ECmdDnLinkError, err);
       
   741         }
       
   742 
       
   743     TRACE_PRN_IF_ERR(err);
       
   744     }
       
   745 
       
   746 // -----------------------------------------------------------------------------
       
   747 // CVoIPDownlinkThread::GetFrameMode
       
   748 //
       
   749 // -----------------------------------------------------------------------------
       
   750 //
       
   751 void CVoIPDownlinkThread::GetFrameMode()
       
   752     {
       
   753     TInt err = KErrNotSupported;
       
   754 
       
   755     if (iErrConcealmentIntfc)
       
   756         {
       
   757         // not available through CIs -> return local value
       
   758         iShared.iMutex.Wait();
       
   759         iShared.iCodecSettings.iFrameMode = iFrameMode;
       
   760         iShared.iMutex.Signal();
       
   761         err = KErrNone;
       
   762         }
       
   763 
       
   764     SendCmd(ECmdGetFrameModeComplete, err);
       
   765     TRACE_PRN_IF_ERR(err);
       
   766     }
       
   767 
       
   768 // -----------------------------------------------------------------------------
       
   769 // CVoIPDownlinkThread::ConcealErrorForNextBuffer
       
   770 //
       
   771 // -----------------------------------------------------------------------------
       
   772 //
       
   773 void CVoIPDownlinkThread::ConcealErrorForNextBuffer()
       
   774     {
       
   775     TInt err = KErrNotSupported;
       
   776 
       
   777     if (iErrConcealmentIntfc)
       
   778         {
       
   779         err = iErrConcealmentIntfc->ConcealErrorForNextBuffer();
       
   780         }
       
   781 
       
   782     if (err != KErrNone)
       
   783         {
       
   784         SendCmd(ECmdDnLinkError, err);
       
   785         }
       
   786 
       
   787     TRACE_PRN_IF_ERR(err);
       
   788     }
       
   789 
       
   790 // -----------------------------------------------------------------------------
       
   791 // CVoIPDownlinkThread::SetCng
       
   792 //
       
   793 // -----------------------------------------------------------------------------
       
   794 //
       
   795 void CVoIPDownlinkThread::SetCng()
       
   796     {
       
   797     TInt err = KErrNotSupported;
       
   798 
       
   799     if (iStatus == EReady)
       
   800         {
       
   801         iShared.iMutex.Wait();
       
   802         TBool cng = iShared.iCodecSettings.iCng;
       
   803         iShared.iMutex.Signal();
       
   804 
       
   805         if (iCodecID == KMccFourCCIdG711 && iG711DecoderIntfc)
       
   806             {
       
   807             err = iG711DecoderIntfc->SetCng(cng);
       
   808             }
       
   809         else
       
   810             {
       
   811             if (iCodecID == KMccFourCCIdILBC && iIlbcDecoderIntfc)
       
   812                 {
       
   813                 err = iIlbcDecoderIntfc->SetCng(cng);
       
   814                 }
       
   815             }
       
   816         }
       
   817 
       
   818     if (err != KErrNone)
       
   819         {
       
   820         SendCmd(ECmdDnLinkError, err);
       
   821         }
       
   822 
       
   823     TRACE_PRN_IF_ERR(err);
       
   824     }
       
   825 
       
   826 // -----------------------------------------------------------------------------
       
   827 // CVoIPDownlinkThread::GetCng
       
   828 //
       
   829 // -----------------------------------------------------------------------------
       
   830 //
       
   831 void CVoIPDownlinkThread::GetCng()
       
   832     {
       
   833     TInt err = KErrNotSupported;
       
   834 
       
   835     if (iStatus == EReady)
       
   836         {
       
   837         TBool cng = EFalse;
       
   838 
       
   839         if (iCodecID == KMccFourCCIdG711 && iG711DecoderIntfc)
       
   840             {
       
   841             err = iG711DecoderIntfc->GetCng(cng);
       
   842             }
       
   843         else
       
   844             {
       
   845             if (iCodecID == KMccFourCCIdILBC && iIlbcDecoderIntfc)
       
   846                 {
       
   847                 err = iIlbcDecoderIntfc->GetCng(cng);
       
   848                 }
       
   849             }
       
   850 
       
   851         iShared.iMutex.Wait();
       
   852         iShared.iCodecSettings.iCng = cng;
       
   853         iShared.iMutex.Signal();
       
   854         }
       
   855 
       
   856     SendCmd(ECmdGetCngComplete, err);
       
   857     TRACE_PRN_IF_ERR(err);
       
   858     }
       
   859 
       
   860 // -----------------------------------------------------------------------------
       
   861 // CVoIPDownlinkThread::SetPlc
       
   862 //
       
   863 // -----------------------------------------------------------------------------
       
   864 //
       
   865 void CVoIPDownlinkThread::SetPlc()
       
   866     {
       
   867     TInt err = KErrNotSupported;
       
   868 
       
   869     if (iStatus == EReady)
       
   870         {
       
   871         if (iCodecID == KMccFourCCIdG711 && iG711DecoderIntfc)
       
   872             {
       
   873             iShared.iMutex.Wait();
       
   874             iPlc = iShared.iCodecSettings.iPlc;
       
   875             iShared.iMutex.Signal();
       
   876             err = iG711DecoderIntfc->SetPlc(iPlc);
       
   877             }
       
   878         }
       
   879 
       
   880     if (err != KErrNone)
       
   881         {
       
   882         SendCmd(ECmdDnLinkError, err);
       
   883         }
       
   884 
       
   885     TRACE_PRN_IF_ERR(err);
       
   886     }
       
   887 
       
   888 // -----------------------------------------------------------------------------
       
   889 // CVoIPDownlinkThread::GetPlc
       
   890 //
       
   891 // -----------------------------------------------------------------------------
       
   892 //
       
   893 void CVoIPDownlinkThread::GetPlc()
       
   894     {
       
   895     TInt err = KErrNotSupported;
       
   896 
       
   897     if (iCodecID == KMccFourCCIdG711 && iG711DecoderIntfc)
       
   898         {
       
   899         // not available through CIs -> return local value
       
   900         iShared.iMutex.Wait();
       
   901         iShared.iCodecSettings.iPlc = iPlc;
       
   902         iShared.iMutex.Signal();
       
   903         err = KErrNone;
       
   904         }
       
   905 
       
   906     SendCmd(ECmdGetPlcComplete, err);
       
   907     TRACE_PRN_IF_ERR(err);
       
   908     }
       
   909 
       
   910 // -----------------------------------------------------------------------------
       
   911 // CVoIPDownlinkThread::BadLsfNextBuffer
       
   912 //
       
   913 // -----------------------------------------------------------------------------
       
   914 //
       
   915 void CVoIPDownlinkThread::BadLsfNextBuffer()
       
   916     {
       
   917     TInt err = KErrNotSupported;
       
   918 
       
   919     if (iStatus == EStreaming)
       
   920         {
       
   921         if (iCodecID == KMccFourCCIdG729 && iG729DecoderIntfc)
       
   922             {
       
   923             err = iG729DecoderIntfc->BadLsfNextBuffer();
       
   924             }
       
   925         }
       
   926 
       
   927     if (err != KErrNone)
       
   928         {
       
   929         SendCmd(ECmdDnLinkError, err);
       
   930         }
       
   931 
       
   932     TRACE_PRN_IF_ERR(err);
       
   933     }
       
   934 
       
   935 // -----------------------------------------------------------------------------
       
   936 // CVoIPDownlinkThread::ConfigureJitterBufferL
       
   937 // -----------------------------------------------------------------------------
       
   938 //
       
   939 void CVoIPDownlinkThread::ConfigureJitterBufferL()
       
   940     {
       
   941     TInt err = KErrNone;
       
   942 
       
   943     if (iCodecID != KMMFFourCCCodePCM16)
       
   944         {
       
   945         if (iJitterBuffer)
       
   946             {
       
   947             delete iJitterBuffer;
       
   948             iJitterBuffer = NULL;
       
   949             }
       
   950         iJitterBuffer = CVoIPJitterBuffer::NewL(this);
       
   951 
       
   952         if (iAddJBuffer)
       
   953             {
       
   954             delete iAddJBuffer;
       
   955             iAddJBuffer = NULL;
       
   956             }
       
   957         iAddJBuffer = CMMFDataBuffer::NewL(iMaxBufLen);
       
   958 
       
   959         if (iGetJBuffer)
       
   960             {
       
   961             delete iGetJBuffer;
       
   962             iGetJBuffer = NULL;
       
   963             }
       
   964         iGetJBuffer = CMMFDataBuffer::NewL(iMaxBufLen);
       
   965 
       
   966         if (iJitterBuffer && iAddJBuffer && iGetJBuffer)
       
   967             {
       
   968             TRACE_PRN_N(_L("VoIP::ConfigureJitterBufferL [OK]"));
       
   969 
       
   970             TVoIPJBConfig conf;
       
   971             iShared.iMutex.Wait();
       
   972             conf.iSampleInterval = iShared.iJBConfig.iSampleInterval;
       
   973             conf.iJitterLatency = iShared.iJBConfig.iJitterLatency;
       
   974             conf.iJBBufferLength = iShared.iJBConfig.iJBBufferLength;
       
   975             conf.iJBThreshold = iShared.iJBConfig.iJBThreshold;
       
   976             conf.iJBInactivityTimeOut
       
   977                     = iShared.iJBConfig.iJBInactivityTimeOut;
       
   978             // TODO: add tone playback params
       
   979             //conf.iJBPlayToneTimeout = ?;
       
   980             //conf.iJBPlayToneDuration = ?;
       
   981             //conf.iJBPlayToneFrequency = ?;
       
   982             iShared.iMutex.Signal();
       
   983 
       
   984             iJitterBuffer->SetupL(iCodecID, conf);
       
   985             iBufLen = iMaxBufLen;
       
   986             err = DoChunk(KChunkDNL, iBufLen, iMaxBufLen);
       
   987             }
       
   988         else
       
   989             {
       
   990             err = KErrGeneral;
       
   991             }
       
   992         }
       
   993 
       
   994     if (err != KErrNone)
       
   995         {
       
   996         Stop();
       
   997         iMsgBuffer.iStatus = err;
       
   998         }
       
   999     else
       
  1000         {
       
  1001         // Notify client there is buffer ready to be filled
       
  1002         iMsgBuffer.iStatus = iChunk.Handle();
       
  1003         iMsgBuffer.iInt = iBufLen;
       
  1004         }
       
  1005 
       
  1006     // This is the only time we will send ECmdFillBuffer in JB mode to
       
  1007     // indicate to the client we are ready to receive packets of iBufLen size.
       
  1008     iMsgBuffer.iRequest = ECmdFillBuffer;
       
  1009     iMsgQueue.Send(iMsgBuffer);
       
  1010 
       
  1011     TRACE_PRN_IF_ERR(err);
       
  1012     }
       
  1013 
       
  1014 // -----------------------------------------------------------------------------
       
  1015 // CVoIPDownlinkThread::ResetJitterBuffer
       
  1016 // -----------------------------------------------------------------------------
       
  1017 //
       
  1018 void CVoIPDownlinkThread::ResetJitterBuffer()
       
  1019     {
       
  1020     if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
  1021         {
       
  1022         iShared.iMutex.Wait();
       
  1023         TBool playTone = iShared.iBool;
       
  1024         iShared.iMutex.Signal();
       
  1025         iJitterBuffer->ResetBuffer(playTone);
       
  1026         }
       
  1027     }
       
  1028 
       
  1029 // -----------------------------------------------------------------------------
       
  1030 // CVoIPDownlinkThread::JBDelayDown
       
  1031 // -----------------------------------------------------------------------------
       
  1032 //
       
  1033 void CVoIPDownlinkThread::JBDelayDown()
       
  1034     {
       
  1035     if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
  1036         {
       
  1037         iJitterBuffer->DelayDown();
       
  1038         }
       
  1039     }
       
  1040 
       
  1041 // -----------------------------------------------------------------------------
       
  1042 // CVoIPDownlinkThread::JBDelayUp
       
  1043 // -----------------------------------------------------------------------------
       
  1044 //
       
  1045 void CVoIPDownlinkThread::JBDelayUp()
       
  1046     {
       
  1047     if (iJitterBuffer && iCodecID != KMMFFourCCCodePCM16)
       
  1048         {
       
  1049         iJitterBuffer->DelayUp();
       
  1050         }
       
  1051     }
       
  1052 
       
  1053 // -----------------------------------------------------------------------------
       
  1054 // CVoIPDownlinkThread::SendCmd
       
  1055 // Completes active object's request and sets shared data command value to
       
  1056 // one of the user requested commands.
       
  1057 // -----------------------------------------------------------------------------
       
  1058 //
       
  1059 void CVoIPDownlinkThread::SendCmd(TUserCommand aCmd, TInt aError)
       
  1060     {
       
  1061     iShared.iMutex.Wait();
       
  1062 
       
  1063     iShared.iCmd = aCmd;
       
  1064     TRequestStatus* status = iShared.iMnThreadStatus;
       
  1065 
       
  1066     if (status)
       
  1067         {
       
  1068         if (status->Int() == KRequestPending)
       
  1069             {
       
  1070             RThread t;
       
  1071             TInt err = t.Open(iShared.iMainThreadID);
       
  1072             if (err == KErrNone)
       
  1073                 {
       
  1074                 t.RequestComplete(status, aError);
       
  1075                 }
       
  1076             }
       
  1077         }
       
  1078 
       
  1079     iShared.iMutex.Signal();
       
  1080     }
       
  1081 
       
  1082 // -----------------------------------------------------------------------------
       
  1083 // CVoIPDownlinkThread::Event
       
  1084 // From MQueueHandlerObserverSrv
       
  1085 // -----------------------------------------------------------------------------
       
  1086 //
       
  1087 void CVoIPDownlinkThread::Event(TInt aEventType, TInt /*aError*/)
       
  1088     {
       
  1089     switch (aEventType)
       
  1090         {
       
  1091         case ECmdStartDownlink:
       
  1092             {
       
  1093             Start();
       
  1094             break;
       
  1095             }
       
  1096         case ECmdStopDownlink:
       
  1097             {
       
  1098             if (iStatus == EStreaming)
       
  1099                 {
       
  1100                 Stop();
       
  1101                 }
       
  1102             break;
       
  1103             }
       
  1104         case ECmdBufferFilled:
       
  1105             {
       
  1106             BufferFilled();
       
  1107             break;
       
  1108             }
       
  1109         case ECmdGetVolume:
       
  1110             {
       
  1111             GetVolume();
       
  1112             break;
       
  1113             }
       
  1114         case ECmdSetVolume:
       
  1115             {
       
  1116             SetVolume();
       
  1117             break;
       
  1118             }
       
  1119         case ECmdSetAudioDevice:
       
  1120             {
       
  1121             TRAPD(err, SetAudioDeviceL());
       
  1122             if (err != KErrNone)
       
  1123                 {
       
  1124                 SendCmd(ECmdDnLinkError, err);
       
  1125                 }
       
  1126             break;
       
  1127             }
       
  1128         case ECmdGetAudioDevice:
       
  1129             {
       
  1130             TRAPD(err, GetAudioDeviceL());
       
  1131             if (err != KErrNone)
       
  1132                 {
       
  1133                 SendCmd(ECmdDnLinkError, err);
       
  1134                 }
       
  1135             break;
       
  1136             }
       
  1137         case ECmdSetIlbcCodecMode:
       
  1138             {
       
  1139             SetIlbcCodecMode();
       
  1140             break;
       
  1141             }
       
  1142         case ECmdGetIlbcCodecMode:
       
  1143             {
       
  1144             GetIlbcCodecMode();
       
  1145             break;
       
  1146             }
       
  1147         case ECmdSetG711CodecMode:
       
  1148             {
       
  1149             SetG711CodecMode();
       
  1150             break;
       
  1151             }
       
  1152         case ECmdGetG711CodecMode:
       
  1153             {
       
  1154             GetG711CodecMode();
       
  1155             break;
       
  1156             }
       
  1157         case ECmdSetFrameMode:
       
  1158             {
       
  1159             SetFrameMode();
       
  1160             break;
       
  1161             }
       
  1162         case ECmdGetFrameMode:
       
  1163             {
       
  1164             GetFrameMode();
       
  1165             break;
       
  1166             }
       
  1167         case ECmdFrameModeRqrdForEC:
       
  1168             {
       
  1169             FrameModeRqrdForEC();
       
  1170             break;
       
  1171             }
       
  1172         case ECmdConcealErrForNextBuf:
       
  1173             {
       
  1174             ConcealErrorForNextBuffer();
       
  1175             break;
       
  1176             }
       
  1177         case ECmdSetCng:
       
  1178             {
       
  1179             SetCng();
       
  1180             break;
       
  1181             }
       
  1182         case ECmdGetCng:
       
  1183             {
       
  1184             GetCng();
       
  1185             break;
       
  1186             }
       
  1187         case ECmdSetPlc:
       
  1188             {
       
  1189             SetPlc();
       
  1190             break;
       
  1191             }
       
  1192         case ECmdGetPlc:
       
  1193             {
       
  1194             GetPlc();
       
  1195             break;
       
  1196             }
       
  1197         case ECmdBadLsfNextBuffer:
       
  1198             {
       
  1199             BadLsfNextBuffer();
       
  1200             break;
       
  1201             }
       
  1202         case ECmdVoIPConfigJB:
       
  1203             {
       
  1204             TRAPD(err, ConfigureJitterBufferL());
       
  1205             if (err != KErrNone)
       
  1206                 {
       
  1207                 SendCmd(ECmdDnLinkError, err);
       
  1208                 }
       
  1209             break;
       
  1210             }
       
  1211         case ECmdVoIPResetJB:
       
  1212             {
       
  1213             ResetJitterBuffer();
       
  1214             break;
       
  1215             }
       
  1216         case ECmdVoIPJBDelayDown:
       
  1217             {
       
  1218             JBDelayDown();
       
  1219             break;
       
  1220             }
       
  1221         case ECmdVoIPJBDelayUp:
       
  1222             {
       
  1223             JBDelayUp();
       
  1224             break;
       
  1225             }
       
  1226         case ECmdTerminateThread:
       
  1227         default:
       
  1228             {
       
  1229             if (iStatus == EStreaming)
       
  1230                 {
       
  1231                 Stop();
       
  1232                 }
       
  1233             // if unknown exception is raised exit thread
       
  1234             CActiveScheduler::Stop();
       
  1235             break;
       
  1236             }
       
  1237         }
       
  1238     }
       
  1239 
       
  1240 // -----------------------------------------------------------------------------
       
  1241 // CVoIPDownlinkThread::Event
       
  1242 // From MJitterBufferObserver
       
  1243 // -----------------------------------------------------------------------------
       
  1244 //
       
  1245 void CVoIPDownlinkThread::EventJB(TInt aEventType, TInt aError)
       
  1246     {
       
  1247     switch (aEventType)
       
  1248         {
       
  1249         case MJitterBufferObserver::EBufferReadyToPlay:
       
  1250             {
       
  1251             if (iStatus == EStreaming)
       
  1252                 {
       
  1253                 iDevSoundBufPtr->Data() = iGetJBuffer->Data();
       
  1254                 iDevSound->PlayData();
       
  1255                 TRACE_PRN_N1(_L("SAMPLES-PLAYED [%d]"), iSamplesPlayedCount++);
       
  1256                 }
       
  1257             break;
       
  1258             }
       
  1259         case MJitterBufferObserver::EBufferConsumed:
       
  1260             {
       
  1261             // Notify client (?)
       
  1262             break;
       
  1263             }
       
  1264         case MJitterBufferObserver::EConcealErrorForNextBuffer:
       
  1265             {
       
  1266             ConcealErrorForNextBuffer();
       
  1267             break;
       
  1268             }
       
  1269         case MJitterBufferObserver::EGeneralError:
       
  1270 //        case MJitterBufferObserver::EBufferUnderflow:
       
  1271 //        case MJitterBufferObserver::EBufferOverflow:
       
  1272         default:
       
  1273             {
       
  1274             SendCmd(ECmdDnLinkJBError, aError);
       
  1275             break;
       
  1276             }
       
  1277         }
       
  1278     }
       
  1279 
       
  1280 // End of file