|
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "mmfclientaudiostreamutils.h" |
|
17 #include <mmf/common/mmfstandardcustomcommands.h> |
|
18 #include <mda/common/audio.h> |
|
19 |
|
20 const TInt KSampleRate8000 = 8000; |
|
21 const TInt KSampleRate11025 = 11025; |
|
22 const TInt KSampleRate12000 = 12000; |
|
23 const TInt KSampleRate16000 = 16000; |
|
24 const TInt KSampleRate22050 = 22050; |
|
25 const TInt KSampleRate24000 = 24000; |
|
26 const TInt KSampleRate32000 = 32000; |
|
27 const TInt KSampleRate44100 = 44100; |
|
28 const TInt KSampleRate48000 = 48000; |
|
29 const TInt KSampleRate64000 = 64000; |
|
30 const TInt KSampleRate88200 = 88200; |
|
31 const TInt KSampleRate96000 = 96000; |
|
32 |
|
33 |
|
34 _LIT(KStreamUtilsPanicCategory, "MMFStreamUtils"); |
|
35 |
|
36 enum TStreamUtilsPanic |
|
37 { |
|
38 EPanicBadArgument, |
|
39 EPanicPostConditionViolation, |
|
40 EPanicUnknownSampleRate, |
|
41 EPanicUnknownChannelSetting, |
|
42 EPanicUnknownEncoding |
|
43 }; |
|
44 |
|
45 LOCAL_C void Panic(const TStreamUtilsPanic aReason) |
|
46 { |
|
47 User::Panic(KStreamUtilsPanicCategory, aReason); |
|
48 } |
|
49 |
|
50 /** |
|
51 * |
|
52 * Function to map the channels enum defined in Mda to the one |
|
53 * defined in MMF |
|
54 * |
|
55 */ |
|
56 TUint StreamUtils::MapChannelsMdaToMMFL(TInt aMdaChannels) |
|
57 { |
|
58 if (aMdaChannels >= 0) |
|
59 { |
|
60 if (aMdaChannels & TMdaAudioDataSettings::EChannelsStereo) |
|
61 { |
|
62 return EMMFStereo; |
|
63 } |
|
64 else if ((aMdaChannels == 0) || // zeroed settings (it's valid.) return a default value |
|
65 (aMdaChannels & TMdaAudioDataSettings::EChannelsMono)) |
|
66 { |
|
67 return EMMFMono; |
|
68 } |
|
69 } |
|
70 // Invalid value |
|
71 User::Leave(KErrNotSupported); |
|
72 return 0; |
|
73 } |
|
74 |
|
75 /** |
|
76 * |
|
77 * Function to map the sample rate enum defined in Mda to the one |
|
78 * defined in MMF |
|
79 * |
|
80 */ |
|
81 TUint StreamUtils::MapSampleRateMdaToMMFL(TInt aMdaSampleRate) |
|
82 { |
|
83 switch (aMdaSampleRate) |
|
84 { |
|
85 case TMdaAudioDataSettings::ESampleRate8000Hz: |
|
86 return EMMFSampleRate8000Hz; |
|
87 case TMdaAudioDataSettings::ESampleRate11025Hz: |
|
88 return EMMFSampleRate11025Hz; |
|
89 case TMdaAudioDataSettings::ESampleRate12000Hz: |
|
90 return EMMFSampleRate12000Hz; |
|
91 case TMdaAudioDataSettings::ESampleRate16000Hz: |
|
92 return EMMFSampleRate16000Hz; |
|
93 case TMdaAudioDataSettings::ESampleRate22050Hz: |
|
94 return EMMFSampleRate22050Hz; |
|
95 case TMdaAudioDataSettings::ESampleRate24000Hz: |
|
96 return EMMFSampleRate24000Hz; |
|
97 case TMdaAudioDataSettings::ESampleRate32000Hz: |
|
98 return EMMFSampleRate32000Hz; |
|
99 case TMdaAudioDataSettings::ESampleRate44100Hz: |
|
100 return EMMFSampleRate44100Hz; |
|
101 case TMdaAudioDataSettings::ESampleRate48000Hz: |
|
102 return EMMFSampleRate48000Hz; |
|
103 case TMdaAudioDataSettings::ESampleRate64000Hz: |
|
104 return EMMFSampleRate64000Hz; |
|
105 case TMdaAudioDataSettings::ESampleRate96000Hz: |
|
106 return EMMFSampleRate96000Hz; |
|
107 case TMdaAudioDataSettings::ESampleRateFixed: |
|
108 case TMdaAudioDataSettings::ESampleRateAnyInRange: |
|
109 User::Leave(KErrNotSupported); |
|
110 return 0; |
|
111 case 0: // zeroed settings (it's valid.) return a default value |
|
112 return EMMFSampleRate8000Hz; |
|
113 default: |
|
114 User::Leave(KErrNotSupported); |
|
115 return 0; |
|
116 } |
|
117 } |
|
118 |
|
119 /** |
|
120 * Function to convert the mmf sample rate enum to an actual sample rate value |
|
121 */ |
|
122 TInt StreamUtils::SampleRateAsValue(const TMMFCapabilities& aCaps) |
|
123 { |
|
124 switch (aCaps.iRate) |
|
125 { |
|
126 case EMMFSampleRate8000Hz: |
|
127 return KSampleRate8000; |
|
128 case EMMFSampleRate11025Hz: |
|
129 return KSampleRate11025; |
|
130 case EMMFSampleRate12000Hz: |
|
131 return KSampleRate12000; |
|
132 case EMMFSampleRate16000Hz: |
|
133 return KSampleRate16000; |
|
134 case EMMFSampleRate22050Hz: |
|
135 return KSampleRate22050; |
|
136 case EMMFSampleRate24000Hz: |
|
137 return KSampleRate24000; |
|
138 case EMMFSampleRate32000Hz: |
|
139 return KSampleRate32000; |
|
140 case EMMFSampleRate44100Hz: |
|
141 return KSampleRate44100; |
|
142 case EMMFSampleRate48000Hz: |
|
143 return KSampleRate48000; |
|
144 case EMMFSampleRate64000Hz: |
|
145 return KSampleRate64000; |
|
146 case EMMFSampleRate88200Hz: |
|
147 return KSampleRate88200; |
|
148 case EMMFSampleRate96000Hz: |
|
149 return KSampleRate96000; |
|
150 default: |
|
151 Panic(EPanicUnknownSampleRate); |
|
152 return 0; |
|
153 } |
|
154 } |
|
155 |
|
156 /** |
|
157 * Return the current number of bytes required to render each sample, based |
|
158 * on the given capabilities. This depends on the current encoding and |
|
159 * whether the sample is mono or stereo |
|
160 */ |
|
161 TInt StreamUtils::BytesPerSample(const TMMFCapabilities& aCaps) |
|
162 { |
|
163 TInt noOfChannels = (aCaps.iChannels == EMMFStereo) ? 2 : 1; |
|
164 switch (aCaps.iEncoding) |
|
165 { |
|
166 case EMMFSoundEncoding8BitPCM: |
|
167 case EMMFSoundEncoding8BitALaw: |
|
168 case EMMFSoundEncoding8BitMuLaw: |
|
169 return (1 * noOfChannels); |
|
170 case EMMFSoundEncoding16BitPCM: |
|
171 return (2 * noOfChannels); |
|
172 default: |
|
173 Panic(EPanicUnknownEncoding); |
|
174 return 0; |
|
175 } |
|
176 } |
|
177 /** |
|
178 * CalculateLeftRightBalance |
|
179 * @param aLeft |
|
180 * @param aRight |
|
181 * @param aBalance |
|
182 * Preconditions: |
|
183 * !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight) |
|
184 * y = m x + c |
|
185 * aLeft = m ( aBalance ) + c |
|
186 * when aBalance = KMMFBalanceMaxLeft aLeft = 100 |
|
187 * when aBalance = KMMFBalanceMaxRight aLeft = 0 |
|
188 * 100 = m( KMMFBalanceMaxLeft ) + c |
|
189 * 0 = m( KMMFBalanceMaxRight ) + c |
|
190 * c = -(KMMFBalanceMaxRight) m |
|
191 * 100 = m(KMMFBalanceMaxLeft ) - m(KMMFBalanceMaxRight) |
|
192 * m = 100/(KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) |
|
193 * c = -(KMMFBalanceMaxRight) * 100 /(KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) |
|
194 * aLeft = ( aBalance - KMMFBalanceMaxRight ) * 100 /( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) |
|
195 */ |
|
196 void StreamUtils::CalculateLeftRightBalance( TInt& aLeft, TInt& aRight, TInt aBalance ) |
|
197 { |
|
198 // [ assert precondition that aBalance is within limits ] |
|
199 __ASSERT_DEBUG( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EPanicBadArgument)); |
|
200 |
|
201 //[ Now separate percentage balances out from aBalance ] |
|
202 aLeft = (100 * (aBalance-KMMFBalanceMaxRight)) / (KMMFBalanceMaxLeft-KMMFBalanceMaxRight); |
|
203 aRight = 100 - aLeft; |
|
204 |
|
205 //[ assert post condition that left and right are within range ] |
|
206 __ASSERT_DEBUG( ( (aLeft <= 100) && (aLeft >= 0) ), Panic(EPanicPostConditionViolation)); |
|
207 __ASSERT_DEBUG( ( (aRight <= 100) && (aRight >= 0) ), Panic(EPanicPostConditionViolation)); |
|
208 } |
|
209 |
|
210 /** |
|
211 * CalculateBalance |
|
212 * @param aBalance |
|
213 * @param aLeft |
|
214 * @param aRight |
|
215 * |
|
216 * follows a simple straight line transformation |
|
217 * y = m x + c |
|
218 * m = (KMMFBalanceMaxLeft-KMMFBalanceMaxRight)/ 100 |
|
219 * c = KMMFBalanceMaxRight |
|
220 * by substitution |
|
221 * when aLeft = 0 |
|
222 * KMMFBalanceMaxRight = m * 0 + c |
|
223 * c = KMMFBalanceMaxRight |
|
224 * when aLeft = 100 |
|
225 * KMMFBalanceMaxLeft = m * 100 + KMMFBalanceMaxRight |
|
226 * m = ( KMMFBalanceMaxLeft - KMMFBalanceMaxRight ) /100 |
|
227 */ |
|
228 #ifdef _DEBUG |
|
229 void StreamUtils::CalculateBalance( TInt& aBalance, TInt aLeft, TInt aRight ) |
|
230 #else |
|
231 void StreamUtils::CalculateBalance( TInt& aBalance, TInt aLeft, TInt /*aRight*/ ) |
|
232 #endif // _DEBUG |
|
233 { |
|
234 //[ assert pre conditions ] |
|
235 __ASSERT_DEBUG( (( aLeft + aRight ) == 100 ), Panic( EPanicBadArgument )); |
|
236 __ASSERT_DEBUG( (( 0 <= aLeft) && ( 100 >= aLeft)), Panic( EPanicBadArgument) ); |
|
237 __ASSERT_DEBUG( (( 0 <= aRight) && ( 100 >= aRight)), Panic( EPanicBadArgument) ); |
|
238 |
|
239 aBalance = (aLeft * (KMMFBalanceMaxLeft-KMMFBalanceMaxRight))/100 + KMMFBalanceMaxRight; |
|
240 |
|
241 //[ assert post condition that aBalance is within limits ] |
|
242 __ASSERT_DEBUG( !(aBalance < KMMFBalanceMaxLeft || aBalance > KMMFBalanceMaxRight), Panic(EPanicPostConditionViolation)); |
|
243 |
|
244 } |