sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "mmfclientaudiostreamutils.h" sl@0: #include sl@0: #include sl@0: sl@0: const TInt KSampleRate8000 = 8000; sl@0: const TInt KSampleRate11025 = 11025; sl@0: const TInt KSampleRate12000 = 12000; sl@0: const TInt KSampleRate16000 = 16000; sl@0: const TInt KSampleRate22050 = 22050; sl@0: const TInt KSampleRate24000 = 24000; sl@0: const TInt KSampleRate32000 = 32000; sl@0: const TInt KSampleRate44100 = 44100; sl@0: const TInt KSampleRate48000 = 48000; sl@0: const TInt KSampleRate64000 = 64000; sl@0: const TInt KSampleRate88200 = 88200; sl@0: const TInt KSampleRate96000 = 96000; sl@0: sl@0: sl@0: _LIT(KStreamUtilsPanicCategory, "MMFStreamUtils"); sl@0: sl@0: enum TStreamUtilsPanic sl@0: { sl@0: EPanicBadArgument, sl@0: EPanicPostConditionViolation, sl@0: EPanicUnknownSampleRate, sl@0: EPanicUnknownChannelSetting, sl@0: EPanicUnknownEncoding sl@0: }; sl@0: sl@0: LOCAL_C void Panic(const TStreamUtilsPanic aReason) sl@0: { sl@0: User::Panic(KStreamUtilsPanicCategory, aReason); sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * Function to map the channels enum defined in Mda to the one sl@0: * defined in MMF sl@0: * sl@0: */ sl@0: TUint StreamUtils::MapChannelsMdaToMMFL(TInt aMdaChannels) sl@0: { sl@0: if (aMdaChannels >= 0) sl@0: { sl@0: if (aMdaChannels & TMdaAudioDataSettings::EChannelsStereo) sl@0: { sl@0: return EMMFStereo; sl@0: } sl@0: else if ((aMdaChannels == 0) || // zeroed settings (it's valid.) return a default value sl@0: (aMdaChannels & TMdaAudioDataSettings::EChannelsMono)) sl@0: { sl@0: return EMMFMono; sl@0: } sl@0: } sl@0: // Invalid value sl@0: User::Leave(KErrNotSupported); sl@0: return 0; sl@0: } sl@0: sl@0: /** sl@0: * sl@0: * Function to map the sample rate enum defined in Mda to the one sl@0: * defined in MMF sl@0: * sl@0: */ sl@0: TUint StreamUtils::MapSampleRateMdaToMMFL(TInt aMdaSampleRate) sl@0: { sl@0: switch (aMdaSampleRate) sl@0: { sl@0: case TMdaAudioDataSettings::ESampleRate8000Hz: sl@0: return EMMFSampleRate8000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate11025Hz: sl@0: return EMMFSampleRate11025Hz; sl@0: case TMdaAudioDataSettings::ESampleRate12000Hz: sl@0: return EMMFSampleRate12000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate16000Hz: sl@0: return EMMFSampleRate16000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate22050Hz: sl@0: return EMMFSampleRate22050Hz; sl@0: case TMdaAudioDataSettings::ESampleRate24000Hz: sl@0: return EMMFSampleRate24000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate32000Hz: sl@0: return EMMFSampleRate32000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate44100Hz: sl@0: return EMMFSampleRate44100Hz; sl@0: case TMdaAudioDataSettings::ESampleRate48000Hz: sl@0: return EMMFSampleRate48000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate64000Hz: sl@0: return EMMFSampleRate64000Hz; sl@0: case TMdaAudioDataSettings::ESampleRate96000Hz: sl@0: return EMMFSampleRate96000Hz; sl@0: case TMdaAudioDataSettings::ESampleRateFixed: sl@0: case TMdaAudioDataSettings::ESampleRateAnyInRange: sl@0: User::Leave(KErrNotSupported); sl@0: return 0; sl@0: case 0: // zeroed settings (it's valid.) return a default value sl@0: return EMMFSampleRate8000Hz; sl@0: default: sl@0: User::Leave(KErrNotSupported); sl@0: return 0; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * Function to convert the mmf sample rate enum to an actual sample rate value sl@0: */ sl@0: TInt StreamUtils::SampleRateAsValue(const TMMFCapabilities& aCaps) sl@0: { sl@0: switch (aCaps.iRate) sl@0: { sl@0: case EMMFSampleRate8000Hz: sl@0: return KSampleRate8000; sl@0: case EMMFSampleRate11025Hz: sl@0: return KSampleRate11025; sl@0: case EMMFSampleRate12000Hz: sl@0: return KSampleRate12000; sl@0: case EMMFSampleRate16000Hz: sl@0: return KSampleRate16000; sl@0: case EMMFSampleRate22050Hz: sl@0: return KSampleRate22050; sl@0: case EMMFSampleRate24000Hz: sl@0: return KSampleRate24000; sl@0: case EMMFSampleRate32000Hz: sl@0: return KSampleRate32000; sl@0: case EMMFSampleRate44100Hz: sl@0: return KSampleRate44100; sl@0: case EMMFSampleRate48000Hz: sl@0: return KSampleRate48000; sl@0: case EMMFSampleRate64000Hz: sl@0: return KSampleRate64000; sl@0: case EMMFSampleRate88200Hz: sl@0: return KSampleRate88200; sl@0: case EMMFSampleRate96000Hz: sl@0: return KSampleRate96000; sl@0: default: sl@0: Panic(EPanicUnknownSampleRate); sl@0: return 0; sl@0: } sl@0: } sl@0: sl@0: /** sl@0: * Return the current number of bytes required to render each sample, based sl@0: * on the given capabilities. This depends on the current encoding and sl@0: * whether the sample is mono or stereo sl@0: */ sl@0: TInt StreamUtils::BytesPerSample(const TMMFCapabilities& aCaps) sl@0: { sl@0: TInt noOfChannels = (aCaps.iChannels == EMMFStereo) ? 2 : 1; sl@0: switch (aCaps.iEncoding) sl@0: { sl@0: case EMMFSoundEncoding8BitPCM: sl@0: case EMMFSoundEncoding8BitALaw: sl@0: case EMMFSoundEncoding8BitMuLaw: sl@0: return (1 * noOfChannels); sl@0: case EMMFSoundEncoding16BitPCM: sl@0: return (2 * noOfChannels); sl@0: default: sl@0: Panic(EPanicUnknownEncoding); sl@0: return 0; sl@0: } sl@0: } sl@0: /** sl@0: * CalculateLeftRightBalance sl@0: * @param aLeft sl@0: * @param aRight sl@0: * @param aBalance sl@0: * Preconditions: sl@0: * !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight) sl@0: * y = m x + c sl@0: * aLeft = m ( aBalance ) + c sl@0: * when aBalance = KMMFBalanceMaxLeft aLeft = 100 sl@0: * when aBalance = KMMFBalanceMaxRight aLeft = 0 sl@0: * 100 = m( KMMFBalanceMaxLeft ) + c sl@0: * 0 = m( KMMFBalanceMaxRight ) + c sl@0: * c = -(KMMFBalanceMaxRight) m sl@0: * 100 = m(KMMFBalanceMaxLeft ) - m(KMMFBalanceMaxRight) sl@0: * m = 100/(KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) sl@0: * c = -(KMMFBalanceMaxRight) * 100 /(KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) sl@0: * aLeft = ( aBalance - KMMFBalanceMaxRight ) * 100 /( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) sl@0: */ sl@0: void StreamUtils::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) sl@0: { sl@0: // [ assert precondition that aBalance is within limits ] sl@0: __ASSERT_DEBUG( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EPanicBadArgument)); sl@0: sl@0: //[ Now separate percentage balances out from aBalance ] sl@0: aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight); sl@0: aRight = 100 - aLeft; sl@0: sl@0: //[ assert post condition that left and right are within range ] sl@0: __ASSERT_DEBUG( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPanicPostConditionViolation)); sl@0: __ASSERT_DEBUG( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPanicPostConditionViolation)); sl@0: } sl@0: sl@0: /** sl@0: * CalculateBalance sl@0: * @param aBalance sl@0: * @param aLeft sl@0: * @param aRight sl@0: * sl@0: * follows a simple straight line transformation sl@0: * y = m x + c sl@0: * m = (KMMFBalanceMaxLeft-KMMFBalanceMaxRight)/ 100 sl@0: * c = KMMFBalanceMaxRight sl@0: * by substitution sl@0: * when aLeft = 0 sl@0: * KMMFBalanceMaxRight = m * 0 + c sl@0: * c = KMMFBalanceMaxRight sl@0: * when aLeft = 100 sl@0: * KMMFBalanceMaxLeft = m * 100 + KMMFBalanceMaxRight sl@0: * m = ( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) /100 sl@0: */ sl@0: #ifdef _DEBUG sl@0: void StreamUtils::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) sl@0: #else sl@0: void StreamUtils::CalculateBalance( TInt& aBalance, TInt aLeft, TInt /*aRight*/ ) sl@0: #endif // _DEBUG sl@0: { sl@0: //[ assert pre conditions ] sl@0: __ASSERT_DEBUG( (( aLeft + aRight ) == 100 ), Panic( EPanicBadArgument )); sl@0: __ASSERT_DEBUG( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EPanicBadArgument) ); sl@0: __ASSERT_DEBUG( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EPanicBadArgument) ); sl@0: sl@0: aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight; sl@0: sl@0: //[ assert post condition that aBalance is within limits ] sl@0: __ASSERT_DEBUG( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EPanicPostConditionViolation)); sl@0: sl@0: }