1 /* |
1 /* |
2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
2 * Copyright (c) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). |
3 * All rights reserved. |
3 * All rights reserved. |
4 * This component and the accompanying materials are made available |
4 * This component and the accompanying materials are made available |
5 * under the terms of "Eclipse Public License v1.0" |
5 * under the terms of "Eclipse Public License v1.0" |
6 * which accompanies this distribution, and is available |
6 * which accompanies this distribution, and is available |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
26 #include <d32soundsc.h> |
26 #include <d32soundsc.h> |
27 |
27 |
28 #include "log.h" |
28 #include "log.h" |
29 #include <openmax/il/common/omxilcallbacknotificationif.h> |
29 #include <openmax/il/common/omxilcallbacknotificationif.h> |
30 #include <openmax/il/common/omxilclockcomponentcmdsif.h> |
30 #include <openmax/il/common/omxilclockcomponentcmdsif.h> |
31 #include <openmax/il/extensions/omxilsymbianaudiopcmextensions.h> |
31 #include <openmax/il/shai/OMX_Symbian_AudioExt.h> |
32 #include "omxilpcmrendererprocessingfunction.h" |
32 #include "omxilpcmrendererprocessingfunction.h" |
33 |
33 |
34 const TInt COmxILPcmRendererProcessingFunction::CPFHelper::KMaxMsgQueueEntries; |
34 const TInt COmxILPcmRendererProcessingFunction::CPFHelper::KMaxMsgQueueEntries; |
35 |
35 |
36 COmxILPcmRendererProcessingFunction* |
36 COmxILPcmRendererProcessingFunction* |
310 DEBUG_PRINTF2(_L8("COmxILPcmRendererProcessingFunction::ConfigIndication %X"), aConfigIndex); |
310 DEBUG_PRINTF2(_L8("COmxILPcmRendererProcessingFunction::ConfigIndication %X"), aConfigIndex); |
311 |
311 |
312 OMX_ERRORTYPE err = OMX_ErrorNone; |
312 OMX_ERRORTYPE err = OMX_ErrorNone; |
313 switch(aConfigIndex) |
313 switch(aConfigIndex) |
314 { |
314 { |
315 case OMX_SymbianIndexConfigAudioPcmVolumeRamp: |
315 case OMX_SYMBIANINDEXCONFIGAUDIOPCMVOLUMERAMP: |
316 { |
316 { |
317 const OMX_SYMBIAN_AUDIO_CONFIG_PCM_VOLUMERAMP* |
317 const OMX_SYMBIAN_AUDIO_CONFIG_VOLUMERAMPTYPE* |
318 pPcmVolumeRamp |
318 pPcmVolumeRamp |
319 = static_cast< |
319 = static_cast< |
320 const OMX_SYMBIAN_AUDIO_CONFIG_PCM_VOLUMERAMP*>( |
320 const OMX_SYMBIAN_AUDIO_CONFIG_VOLUMERAMPTYPE*>( |
321 apComponentConfigStructure); |
321 apComponentConfigStructure); |
322 |
322 |
323 if (iPFHelper->SetVolumeRamp(pPcmVolumeRamp->nRampDuration) != KErrNone) |
323 if (iPFHelper->SetVolumeRamp(pPcmVolumeRamp->nRampDuration) != KErrNone) |
324 { |
324 { |
325 err = OMX_ErrorInsufficientResources; |
325 err = OMX_ErrorInsufficientResources; |
739 |
739 |
740 iCurrentBuffer = iParent.iBuffersToEmpty[0]; |
740 iCurrentBuffer = iParent.iBuffersToEmpty[0]; |
741 |
741 |
742 iParent.iBuffersToEmpty.Remove(0); |
742 iParent.iBuffersToEmpty.Remove(0); |
743 |
743 |
744 CMMFDataBuffer* mmfSrcBuffer = static_cast<CMMFDataBuffer*>(iCurrentBuffer->pInputPortPrivate); |
744 TPtr8 ptrData(iCurrentBuffer->pBuffer, iCurrentBuffer->nFilledLen, iCurrentBuffer->nFilledLen); |
745 mmfSrcBuffer->Data().SetLength(iCurrentBuffer->nFilledLen); |
745 |
746 |
|
747 // Attenuate the amplitude of the samples if volume ramping has been changed |
746 // Attenuate the amplitude of the samples if volume ramping has been changed |
748 if (iRampAudioSample) |
747 if (iRampAudioSample) |
749 { |
748 { |
750 iRampAudioSample = RampAudio(mmfSrcBuffer); |
749 iRampAudioSample = RampAudio(ptrData); |
751 } |
750 } |
752 |
751 |
753 // First, check whether the buffer length is sufficient not to cause underflows in the device driver |
752 // First, check whether the buffer length is sufficient not to cause underflows in the device driver |
754 TBool isFilledLengthSufficient = IsBufferLengthSufficient(iCurrentBuffer->nFilledLen); |
753 TBool isFilledLengthSufficient = IsBufferLengthSufficient(iCurrentBuffer->nFilledLen); |
755 // This variable defines whether we should send the data to the driver directly, or append it to an aggregated buffer |
754 // This variable defines whether we should send the data to the driver directly, or append it to an aggregated buffer |
756 // We append the buffer instead of sending it directly, if (i) the buffer is too small, or (ii) we have already aggregated something. |
755 // We append the buffer instead of sending it directly, if (i) the buffer is too small, or (ii) we have already aggregated something. |
757 TBool appendBuffer = (!isFilledLengthSufficient || iCachedPlayBuffer.Length() > 0) ? ETrue : EFalse; |
756 TBool appendBuffer = (!isFilledLengthSufficient || iCachedPlayBuffer.Length() > 0) ? ETrue : EFalse; |
758 if (!appendBuffer) |
757 if (!appendBuffer) |
759 { |
758 { |
760 SendBufferToSoundDevice(mmfSrcBuffer->Data()); |
759 SendBufferToSoundDevice(ptrData); |
761 } |
760 } |
762 else |
761 else |
763 { |
762 { |
764 // Check if we need to allocate the cached buffer |
763 // Check if we need to allocate the cached buffer |
765 if (iCachedPlayBuffer.MaxLength() == 0) |
764 if (iCachedPlayBuffer.MaxLength() == 0) |
772 iParent.iCallbacks.ErrorEventNotification(OMX_ErrorInsufficientResources); |
771 iParent.iCallbacks.ErrorEventNotification(OMX_ErrorInsufficientResources); |
773 return; |
772 return; |
774 } |
773 } |
775 } |
774 } |
776 |
775 |
777 iCachedPlayBuffer.Append(mmfSrcBuffer->Data()); |
776 iCachedPlayBuffer.Append(ptrData); |
778 |
777 |
779 // If we have sufficient length aggregated, play the cached buffer |
778 // If we have sufficient length aggregated, play the cached buffer |
780 // Also if this is the last buffer, we have to play it now, there's nothing left to cache |
779 // Also if this is the last buffer, we have to play it now, there's nothing left to cache |
781 if (IsBufferLengthSufficient(iCachedPlayBuffer.Length()) || iCurrentBuffer->nFlags & OMX_BUFFERFLAG_EOS) |
780 if (IsBufferLengthSufficient(iCachedPlayBuffer.Length()) || iCurrentBuffer->nFlags & OMX_BUFFERFLAG_EOS) |
782 { |
781 { |
1346 iRampSamplesLeft = iRampSamples; |
1345 iRampSamplesLeft = iRampSamples; |
1347 iRampIncr = 0; |
1346 iRampIncr = 0; |
1348 iSkip = ETrue; |
1347 iSkip = ETrue; |
1349 } |
1348 } |
1350 |
1349 |
1351 TBool COmxILPcmRendererProcessingFunction::CAudioDevice::RampAudio(CMMFDataBuffer* aBuffer) |
1350 TBool COmxILPcmRendererProcessingFunction::CAudioDevice::RampAudio(TDes8& aBuffer) |
1352 { |
1351 { |
1353 TInt i=0; |
1352 TInt i=0; |
1354 TInt length = aBuffer->Data().Length()>>1; |
1353 TInt length = aBuffer.Length()>>1; |
1355 if (length == 0) |
1354 if (length == 0) |
1356 { |
1355 { |
1357 return EFalse; |
1356 return EFalse; |
1358 } |
1357 } |
1359 |
1358 |
1360 TInt16* sample = REINTERPRET_CAST(TInt16*,&aBuffer->Data()[0]); |
1359 TInt16* sample = REINTERPRET_CAST(TInt16*,&aBuffer[0]); |
1361 TInt64 theResult(0); |
1360 TInt64 theResult(0); |
1362 while ((i < length) && (iRampIncr < iRampSamples)) |
1361 while ((i < length) && (iRampIncr < iRampSamples)) |
1363 { |
1362 { |
1364 theResult = sample[i]; |
1363 theResult = sample[i]; |
1365 theResult *= iRampIncr; |
1364 theResult *= iRampIncr; |
1583 { |
1582 { |
1584 |
1583 |
1585 TProcMessage message; |
1584 TProcMessage message; |
1586 message.iType = ECloseDeviceOnError; |
1585 message.iType = ECloseDeviceOnError; |
1587 TInt error = iMsgQueue.Send(message); |
1586 TInt error = iMsgQueue.Send(message); |
1588 if (KErrNone != error) |
1587 if (KErrNone == error) |
1589 { |
1588 { |
1590 // only wait if the message was sent into the queue... |
1589 // only wait if the message was sent into the queue... |
1591 iCallerSemaphore.Wait(); |
1590 iCallerSemaphore.Wait(); |
1592 } |
1591 } |
1593 } |
1592 } |