|
1 /* |
|
2 * Copyright (c) 2005-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: Implementation for CBTSACStreamerController class. This class constructs and |
|
15 * communicates with 'BT Audio Streamer' component to do RTP streaming. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "btsacStreamerController.h" |
|
22 #include "debug.h" |
|
23 |
|
24 // Subband codec-specific values |
|
25 // in bluetoothAV.h |
|
26 using namespace SymbianSBC; |
|
27 |
|
28 |
|
29 // CONSTANTS |
|
30 _LIT(KBTAADLL, "btaudioadaptation.dll"); |
|
31 |
|
32 //const TInt KUpgradeTimerDelay = 120000000; // 2 minutes. How often we sill try to upgrade back to a better quality audio. |
|
33 const TInt KRetryTimerDelay = 2000000; // 2 seconds. If something fails, how soon should we retry. |
|
34 const TInt KStabilizationDelay = 2000000; // 2 seconds. Wait this long after bitpool change then start mononitor packet drops again |
|
35 const TInt KDataCollectDelay = 600000; // Time (600ms) to collect packet drop data |
|
36 |
|
37 // All tables below have to formed such a way that highest max bitpool value has to be in position 0 and etc. |
|
38 const TInt KMaxBitpoolValues[] = {59, 48, 40, 34}; // Max bitpool values |
|
39 const TInt KDeviationValues[] = {1000, 100000, 300000, 300000}; // maximum time (ys) between first and last packet dropped event |
|
40 |
|
41 const TInt KNumOfBitpoolValues = sizeof(KMaxBitpoolValues)/sizeof(TInt); |
|
42 #define MAXBITPOOLVALUEMAX KMaxBitpoolValues[0] |
|
43 #define MAXBITPOOLVALUEMIN KMaxBitpoolValues[KNumOfBitpoolValues-1] |
|
44 |
|
45 const float KReconfigureLimitFactor = 0.02; // 2% of during KDataCollectDelay transferred data |
|
46 const float KLimitCheckInterval = ((float)KDataCollectDelay/1000000.0); // Time (seconds) to collect packet drop data |
|
47 |
|
48 // MODULE DATA STRUCTURES |
|
49 |
|
50 // ================= MEMBER FUNCTIONS ======================= |
|
51 |
|
52 // ----------------------------------------------------------------------------- |
|
53 // CBTSACStreamerController::NewL |
|
54 // Two-phased constructor. |
|
55 // ----------------------------------------------------------------------------- |
|
56 // |
|
57 CBTSACStreamerController* CBTSACStreamerController::NewL(MBTAudioAdaptationObserver& aObserver ) |
|
58 { |
|
59 CBTSACStreamerController* self = new (ELeave) CBTSACStreamerController (aObserver); |
|
60 CleanupStack::PushL( self ); |
|
61 self->ConstructL(); |
|
62 CleanupStack::Pop( self ); |
|
63 return self; |
|
64 } |
|
65 |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // Destructor. |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 CBTSACStreamerController::~CBTSACStreamerController() |
|
72 { |
|
73 TRACE_FUNC |
|
74 Cancel(); |
|
75 if(iAudioInput) |
|
76 { |
|
77 iAudioInput->Stop(); |
|
78 iAudioInput->Disconnect(); |
|
79 } |
|
80 delete iPacketDropIoctl; |
|
81 delete iEncoderCI; |
|
82 delete iBTStreamer; |
|
83 delete iAudioInput; |
|
84 iLib.Close(); |
|
85 iTimer.Close(); |
|
86 iBitpoolData.Close(); |
|
87 TRACE_INFO((_L("CBTSACStreamerController::~CBTSACStreamerController() completed"))) |
|
88 } |
|
89 |
|
90 // ----------------------------------------------------------------------------- |
|
91 // CBTSACStreamerController::CBTSACStreamerController |
|
92 // C++ default constructor. |
|
93 // ----------------------------------------------------------------------------- |
|
94 // |
|
95 CBTSACStreamerController::CBTSACStreamerController(MBTAudioAdaptationObserver& aObserver) |
|
96 : CActive( EPriorityNormal ), iObserver(aObserver) |
|
97 { |
|
98 CActiveScheduler::Add(this); |
|
99 } |
|
100 |
|
101 // ----------------------------------------------------------------------------- |
|
102 // CBTSACStreamerController::ConstructL |
|
103 // Symbian 2nd phase constructor. |
|
104 // ----------------------------------------------------------------------------- |
|
105 // |
|
106 void CBTSACStreamerController::ConstructL( ) |
|
107 { |
|
108 TRACE_FUNC |
|
109 |
|
110 User::LeaveIfError(iTimer.CreateLocal()); |
|
111 iThread = RThread(); |
|
112 |
|
113 iBTStreamer = CBTAudioStreamer::NewL(); |
|
114 |
|
115 LEAVE_IF_ERROR( iLib.Load( KBTAADLL ) ); |
|
116 typedef TInt (*TOurLibraryFunction2)(MBTAudioStreamObserver&, MBTAudioErrorObserver&); |
|
117 TOurLibraryFunction2 newL2 = reinterpret_cast<TOurLibraryFunction2>(iLib.Lookup(1)); |
|
118 iAudioInput = (CBTAudioStreamInputBase*)newL2(*iBTStreamer, *this); |
|
119 |
|
120 TInt ret; |
|
121 ret = iAudioInput->Connect(); |
|
122 if (ret) |
|
123 { |
|
124 TRACE_INFO((_L("CBTSACStreamerController::ConstructL() Audio Input Connect Error %d"), ret)) |
|
125 User::Leave(ret); |
|
126 } |
|
127 |
|
128 ret = iAudioInput->SetFormat(KMMFFourCCCodeSBC); |
|
129 if (ret) |
|
130 { |
|
131 TRACE_INFO((_L("CBTSACStreamerController::ConstructL() Audio Input SetFormat Error %d"), ret)) |
|
132 User::Leave(ret); |
|
133 } |
|
134 |
|
135 iEncoderCI = reinterpret_cast<CSbcEncoderIntfc *> (iAudioInput->EncoderInterface(KUidSbcEncoderIntfc)); |
|
136 User::LeaveIfNull(iEncoderCI); |
|
137 |
|
138 InitializeBitpoolDataL(); |
|
139 iState = EStateIdle; |
|
140 |
|
141 TRACE_INFO((_L("CBTSACStreamerController::ConstructL() completed"))) |
|
142 } |
|
143 |
|
144 // ----------------------------------------------------------------------------- |
|
145 // CBTSACStreamerController::StartStream |
|
146 // ----------------------------------------------------------------------------- |
|
147 // |
|
148 TInt CBTSACStreamerController::StartStream(RSocket& aSocket, TInt aFrameLength ) |
|
149 { |
|
150 TRACE_FUNC |
|
151 |
|
152 if (!(iBTStreamer) || !(iAudioInput) ) |
|
153 { |
|
154 return KErrNotFound; |
|
155 } |
|
156 |
|
157 if (iState == EStateError) |
|
158 { |
|
159 iState = EStateIdle; |
|
160 TInt err = iAudioInput->Connect(); |
|
161 if (!err) |
|
162 { |
|
163 err = iAudioInput->SetFormat(KMMFFourCCCodeSBC); |
|
164 } |
|
165 if (err) |
|
166 { |
|
167 TRACE_INFO((_L("CBTSACStreamerController::StartStream() Audio Input initialization Error %d"), err)) |
|
168 return err; |
|
169 } |
|
170 } |
|
171 |
|
172 if (iState == EStateIdle) |
|
173 { |
|
174 TInt err = KErrNone; |
|
175 TRAP( err, iBTStreamer->StartL(aSocket, aFrameLength, iAudioInput, iCurrentBitrate)); |
|
176 |
|
177 if ( err == KErrNone ) |
|
178 { |
|
179 err = iAudioInput->Start(); |
|
180 } |
|
181 |
|
182 if ( err == KErrNone ) |
|
183 { |
|
184 TRACE_INFO((_L("CBTSACStreamerController::StartStream() Sending packet drop IOCTL"))) |
|
185 TRAP( err, iPacketDropIoctl = CActivePacketDropIoctl::NewL(*this, aSocket)); |
|
186 |
|
187 if( err == KErrNone ) |
|
188 { |
|
189 iPacketDropDeviation = 0; |
|
190 iTotalNbrOfDroppedPackets = 0; |
|
191 iState = EStateStreaming; |
|
192 |
|
193 if(iCurrentBitpoolData->iMaxBitpoolValue < iMatchCap.MaxBitpoolValue()) |
|
194 { |
|
195 TRACE_INFO((_L("CBTSACStreamerController::StartStream(), upgrade bitrate."))) |
|
196 // Streaming was stopped when the bitrate was lower than maximum, so upgrade it for starters. |
|
197 // iPacketDropIoctl->Start will be called after self completion. |
|
198 |
|
199 // Update current bitpool data to be highest possible. Highest possible bitpool value can be found from position |
|
200 iCurrentBitpoolData = GetBitpoolData(0); |
|
201 if(iCurrentBitpoolData) |
|
202 { |
|
203 DoSelfComplete(EUpgradeBitrate, KErrNone); |
|
204 } |
|
205 else |
|
206 { |
|
207 err = KErrArgument; |
|
208 } |
|
209 } |
|
210 else if(iMatchCap.MaxBitpoolValue() > iBitpoolData[iBitpoolData.Count() - 1].iMaxBitpoolValue) |
|
211 { |
|
212 // Don't start receive packet drop events if max bitpool value is not bigger than min |
|
213 // bitpool value (we can't downgrade bitpool, we already have lowest possible value). |
|
214 DoSelfComplete(EStartStabilizingTimer, KErrNone); |
|
215 } |
|
216 TRACE_INFO((_L("CBTSACStreamerController::StartStream() completed"))) |
|
217 } |
|
218 } |
|
219 if( err ) |
|
220 { |
|
221 // In case someting went wrong stop both audio adaptation and streamer |
|
222 TRACE_INFO((_L("CBTSACStreamerController::StartStream() *Error: %d"), err)) |
|
223 iAudioInput->Stop(); |
|
224 iAudioInput->Disconnect(); |
|
225 iBTStreamer->Stop(); |
|
226 |
|
227 //make sure iAudioInput->Connect() & SetFormat() get called in StartStream() |
|
228 iState = EStateError; |
|
229 } |
|
230 return err; |
|
231 } |
|
232 else |
|
233 { |
|
234 return KErrAlreadyExists; |
|
235 } |
|
236 } |
|
237 |
|
238 // ----------------------------------------------------------------------------- |
|
239 // CBTSACStreamerController::StopStream |
|
240 // ----------------------------------------------------------------------------- |
|
241 // |
|
242 TInt CBTSACStreamerController::StopStream() |
|
243 { |
|
244 TRACE_FUNC |
|
245 Cancel(); |
|
246 if (!(iBTStreamer) || !(iAudioInput)) |
|
247 { |
|
248 return KErrNotFound; |
|
249 } |
|
250 else if (iState != EStateIdle ) |
|
251 { |
|
252 iAudioInput->Stop(); |
|
253 iBTStreamer->Stop(); |
|
254 delete iPacketDropIoctl; |
|
255 iPacketDropIoctl = NULL; |
|
256 iState = EStateIdle; |
|
257 return KErrNone; |
|
258 } |
|
259 else |
|
260 { |
|
261 return KErrAlreadyExists; |
|
262 } |
|
263 } |
|
264 |
|
265 // ----------------------------------------------------------------------------- |
|
266 // CBTSACStreamerController::ResetAudioInput |
|
267 // ----------------------------------------------------------------------------- |
|
268 // |
|
269 void CBTSACStreamerController::ResetAudioInput() |
|
270 { |
|
271 TRACE_FUNC |
|
272 iAudioInput->Stop(); |
|
273 iAudioInput->Disconnect(); |
|
274 TInt err = iAudioInput->Connect(); |
|
275 if (!err) |
|
276 { |
|
277 err = iAudioInput->SetFormat(KMMFFourCCCodeSBC); |
|
278 } |
|
279 if (err) |
|
280 { |
|
281 TRACE_INFO((_L("CBTSACStreamerController::ResetAudioInput() Audio Input initialization Error %d"), err)) |
|
282 } |
|
283 } |
|
284 |
|
285 // ----------------------------------------------------------------------------- |
|
286 // CBTSACStreamerController::FillCapabilities |
|
287 // ----------------------------------------------------------------------------- |
|
288 // |
|
289 TInt CBTSACStreamerController::FillCapabilities( TSBCCodecCapabilities& aSbc ) |
|
290 { |
|
291 TRACE_FUNC |
|
292 |
|
293 TUint8 itemp = 0x00; |
|
294 // Sampling Frequency |
|
295 TInt ret; |
|
296 RArray<TUint> SupportedSamplingFrequencies; |
|
297 ret = iEncoderCI->GetSupportedSamplingFrequencies(SupportedSamplingFrequencies); |
|
298 if ( !ret) |
|
299 { |
|
300 itemp = 0x00; |
|
301 |
|
302 for (TInt i=0; i<SupportedSamplingFrequencies.Count(); i++ ) |
|
303 { |
|
304 if ( SupportedSamplingFrequencies[i] == TUint(16000) ) |
|
305 { |
|
306 itemp = E16kHz; // E16kHz = 0x8 |
|
307 continue; |
|
308 } |
|
309 if ( SupportedSamplingFrequencies[i] == TUint(32000) ) |
|
310 { |
|
311 itemp |= E32kHz; // E32kHz = 0x4 |
|
312 continue; |
|
313 } |
|
314 if ( SupportedSamplingFrequencies[i] == TUint(44100) ) |
|
315 { |
|
316 itemp |= E44100Hz; // E44100Hz = 0x2 |
|
317 continue; |
|
318 } |
|
319 if ( SupportedSamplingFrequencies[i] == TUint(48000) ) |
|
320 { |
|
321 itemp |= E48kHz; // E48kHz = 0x1 |
|
322 continue; |
|
323 } |
|
324 } |
|
325 aSbc.SetSamplingFrequencies(itemp); |
|
326 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder Sampling Frequencies: %d"), itemp)) |
|
327 } |
|
328 else |
|
329 { |
|
330 return ret; |
|
331 } |
|
332 |
|
333 // Channel mode |
|
334 RArray<CSbcEncoderIntfc::TSbcChannelMode> SupportedChannelModes; |
|
335 ret = iEncoderCI->GetSupportedChannelModes(SupportedChannelModes); |
|
336 if ( !ret ) |
|
337 { |
|
338 itemp = 0x00; |
|
339 |
|
340 for (TInt i=0; i<SupportedChannelModes.Count(); i++ ) |
|
341 { |
|
342 if ( SupportedChannelModes[i] == CSbcEncoderIntfc::ESbcChannelMono) |
|
343 { |
|
344 itemp = EMono; // EMono = 0x8 |
|
345 continue; |
|
346 } |
|
347 if ( SupportedChannelModes[i] == CSbcEncoderIntfc::ESbcChannelDual ) |
|
348 { |
|
349 itemp |= EDualChannel; // EDualChannel = 0x4 |
|
350 continue; |
|
351 } |
|
352 if ( SupportedChannelModes[i] == CSbcEncoderIntfc::ESbcChannelStereo ) |
|
353 { |
|
354 itemp |= EStereo; // EStereo = 0x2 |
|
355 continue; |
|
356 } |
|
357 if ( SupportedChannelModes[i] == CSbcEncoderIntfc::ESbcChannelJointStereo ) |
|
358 { |
|
359 itemp |= EJointStereo; // EJointStereo = 0x1 |
|
360 continue; |
|
361 } |
|
362 } |
|
363 aSbc.SetChannelModes(itemp); |
|
364 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder Channel modes: %d"), itemp)) |
|
365 } |
|
366 else |
|
367 { |
|
368 return ret; |
|
369 } |
|
370 |
|
371 // Blocks |
|
372 RArray<TUint> SupportedNumOfBlocks; |
|
373 ret = iEncoderCI->GetSupportedNumOfBlocks(SupportedNumOfBlocks); |
|
374 if ( !ret ) |
|
375 { |
|
376 itemp = 0x00; |
|
377 |
|
378 for (TInt i=0; i<SupportedNumOfBlocks.Count(); i++ ) |
|
379 { |
|
380 if ( SupportedNumOfBlocks[i] == TUint(4)) |
|
381 { |
|
382 itemp = EBlockLenFour; // EBlockLenFour = 0x8 |
|
383 continue; |
|
384 } |
|
385 if ( SupportedNumOfBlocks[i] == TUint(8) ) |
|
386 { |
|
387 itemp |= EBlockLenEight; // EBlockLenEight = 0x4 |
|
388 continue; |
|
389 } |
|
390 if ( SupportedNumOfBlocks[i] == TUint(12) ) |
|
391 { |
|
392 itemp |= EBlockLenTwelve; // EBlockLenTwelve = 0x2 |
|
393 continue; |
|
394 } |
|
395 if ( SupportedNumOfBlocks[i] == TUint(16) ) |
|
396 { |
|
397 itemp |= EBlockLenSixteen; // EBlockLenSixteen = 0x1 |
|
398 continue; |
|
399 } |
|
400 } |
|
401 aSbc.SetBlockLengths(itemp); |
|
402 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder Blocks: %d"), itemp)) |
|
403 } |
|
404 else |
|
405 { |
|
406 return ret; |
|
407 } |
|
408 |
|
409 // Subbands |
|
410 RArray<TUint> SupportedNumOfSubbands; |
|
411 ret = iEncoderCI->GetSupportedNumOfSubbands(SupportedNumOfSubbands); |
|
412 if ( !ret ) |
|
413 { |
|
414 itemp = 0x0; |
|
415 for (TInt i=0; i<SupportedNumOfSubbands.Count(); i++ ) |
|
416 { |
|
417 if ( SupportedNumOfSubbands[i] == TUint(4) ) |
|
418 { |
|
419 itemp = EFourSubbands; // EFourSubbands = 0x02 |
|
420 continue; |
|
421 } |
|
422 if ( SupportedNumOfSubbands[i] == TUint(8) ) |
|
423 { |
|
424 itemp |= EEightSubbands; // EEightSubbands = 0x01 |
|
425 continue; |
|
426 } |
|
427 } |
|
428 aSbc.SetSubbands(itemp); |
|
429 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder SubBands: %d"), itemp)) |
|
430 } |
|
431 else |
|
432 { |
|
433 return ret; |
|
434 } |
|
435 |
|
436 // allocation method bitmask |
|
437 RArray<CSbcEncoderIntfc::TSbcAllocationMethod> SupportedAllocationMethods; |
|
438 ret = iEncoderCI->GetSupportedAllocationMethods(SupportedAllocationMethods); |
|
439 if ( !ret ) |
|
440 { |
|
441 itemp = 0x0; |
|
442 for (TInt i=0; i<SupportedAllocationMethods.Count(); i++ ) |
|
443 { |
|
444 if ( SupportedAllocationMethods[i] == CSbcEncoderIntfc::ESbcAllocationSNR ) |
|
445 { |
|
446 itemp = ESNR; // ESNR = 0x02 |
|
447 continue; |
|
448 } |
|
449 if ( SupportedAllocationMethods[i] == CSbcEncoderIntfc::ESbcAllocationLoudness ) |
|
450 { |
|
451 itemp |= ELoudness; // ELoudness = 0x01 |
|
452 continue; |
|
453 } |
|
454 } |
|
455 aSbc.SetAllocationMethods(itemp); |
|
456 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder Alloc method: %d"), itemp)) |
|
457 } |
|
458 else |
|
459 { |
|
460 return ret; |
|
461 } |
|
462 |
|
463 // bitpools |
|
464 TUint MinSupportedBitpoolSize; TUint MaxSupportedBitpoolSize; |
|
465 ret = iEncoderCI->GetSupportedBitpoolRange(MinSupportedBitpoolSize, |
|
466 MaxSupportedBitpoolSize); |
|
467 if ( !ret ) |
|
468 { |
|
469 if (MaxSupportedBitpoolSize > MAXBITPOOLVALUEMAX) |
|
470 { |
|
471 MaxSupportedBitpoolSize = MAXBITPOOLVALUEMAX; |
|
472 } |
|
473 // TUint8 to TInt |
|
474 aSbc.SetMaxBitpoolValue(MaxSupportedBitpoolSize); |
|
475 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder Max bitpool: %d"), MaxSupportedBitpoolSize)) |
|
476 aSbc.SetMinBitpoolValue(MinSupportedBitpoolSize); |
|
477 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Encoder Min bitpool: %d"), MinSupportedBitpoolSize)) |
|
478 } |
|
479 else |
|
480 { |
|
481 return ret; |
|
482 } |
|
483 |
|
484 // save our local copy, 9 bytes on stack |
|
485 iLocalCap = aSbc; |
|
486 |
|
487 TRACE_INFO((_L("CBTSACStreamerController::FillCapabilities() Return: %d"), ret)); |
|
488 return ret; |
|
489 } |
|
490 |
|
491 // ----------------------------------------------------------------------------- |
|
492 // CBTSACStreamerController::ConfigureSEP |
|
493 // ----------------------------------------------------------------------------- |
|
494 // |
|
495 TInt CBTSACStreamerController::ConfigureSEP( TSBCCodecCapabilities& aDec ) |
|
496 { |
|
497 TRACE_FUNC |
|
498 TInt err = KErrNone; |
|
499 TRAP(err, InitializeBitpoolDataL()); |
|
500 if(err) |
|
501 return err; |
|
502 |
|
503 err = GetMatchingCaps(aDec); |
|
504 if(!err) |
|
505 { |
|
506 CheckAndAdjustBitpool(aDec); |
|
507 // Save the matching Caps |
|
508 iMatchCap = aDec; |
|
509 ReorganizeBitpoolTable(iMatchCap.MaxBitpoolValue()); |
|
510 err = SetCurrentBitpoolData(iMatchCap.MaxBitpoolValue()); |
|
511 if(!err) |
|
512 { |
|
513 iEncoderCI->SetBitpoolSize(iMatchCap.MaxBitpoolValue()); |
|
514 // configure encoder |
|
515 err = iEncoderCI->ApplyConfig(); |
|
516 } |
|
517 } |
|
518 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEP() return: %d"), err)) |
|
519 return err; |
|
520 } |
|
521 |
|
522 // ----------------------------------------------------------------------------- |
|
523 // CBTSACStreamerController::ConfigureSEPBitpool |
|
524 // ----------------------------------------------------------------------------- |
|
525 // |
|
526 TInt CBTSACStreamerController::ConfigureSEPBitpool(EOngoingAction aAction) |
|
527 { |
|
528 TRACE_FUNC |
|
529 TInt err = KErrNone; |
|
530 TSBCCodecCapabilities newDecConfiguration; |
|
531 memset(&newDecConfiguration, 0, sizeof(newDecConfiguration)); |
|
532 newDecConfiguration = iMatchCap; |
|
533 TInt nextIndex = (aAction == EDowngradeBitrate) ? iCurrentBitpoolData->iDownBitpoolIndex : iCurrentBitpoolData->iUpBitpoolIndex; |
|
534 if(!IndexValid(nextIndex)) |
|
535 { |
|
536 return KErrArgument; |
|
537 } |
|
538 TInt BitpoolValue = iBitpoolData[nextIndex].iMaxBitpoolValue; |
|
539 newDecConfiguration.SetMaxBitpoolValue(BitpoolValue); |
|
540 CheckAndAdjustBitpool(newDecConfiguration); |
|
541 |
|
542 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEPBitpool() Current FrameLength: %d"), iCurrentFrameLength)) |
|
543 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEPBitpool() Current Bitrate: %d"), iCurrentBitrate)) |
|
544 |
|
545 err = iBTStreamer->SetNewFrameLength(iCurrentFrameLength, iCurrentBitrate); |
|
546 if(!err) |
|
547 { |
|
548 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEPBitpool(), Reconfiguring the encoder..."))) |
|
549 iEncoderCI->SetBitpoolSize(newDecConfiguration.MaxBitpoolValue()); |
|
550 // configure encoder |
|
551 err = iEncoderCI->ApplyConfig(); |
|
552 if(!err) |
|
553 { |
|
554 err = SetCurrentBitpoolData(newDecConfiguration.MaxBitpoolValue()); |
|
555 if(!err) |
|
556 { |
|
557 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEPBitpool(): Current BP: %d"), iCurrentBitpoolData->iMaxBitpoolValue)) |
|
558 } |
|
559 } |
|
560 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEPBitpool() The encoder reconfigured."))) |
|
561 } |
|
562 TRACE_INFO((_L("CBTSACStreamerController::ConfigureSEPBitpool() return: %d"), err)) |
|
563 return err; |
|
564 } |
|
565 |
|
566 // ----------------------------------------------------------------------------- |
|
567 // CBTSACStreamerController::FrameLength |
|
568 // ----------------------------------------------------------------------------- |
|
569 // |
|
570 TInt CBTSACStreamerController::FrameLength() const |
|
571 { |
|
572 TRACE_INFO((_L("CBTSACStreamerController::FrameLength() = %d"), iCurrentFrameLength)) |
|
573 return iCurrentFrameLength; |
|
574 } |
|
575 |
|
576 // ----------------------------------------------------------------------------- |
|
577 // CBTSACStreamerController::GetMatchingCaps |
|
578 // ----------------------------------------------------------------------------- |
|
579 // |
|
580 TInt CBTSACStreamerController::GetMatchingCaps(TSBCCodecCapabilities& aCaps) |
|
581 { |
|
582 TRACE_FUNC |
|
583 TInt ret = KErrNone; |
|
584 TUint8 MatchingFreq, MatchingChnl, MatchingBlck, MatchingSub, MatchingAlloc; |
|
585 |
|
586 MatchingFreq = (iLocalCap.SamplingFrequencies() & aCaps.SamplingFrequencies()); |
|
587 MatchingChnl = (iLocalCap.ChannelModes() & aCaps.ChannelModes()); |
|
588 MatchingBlck = (iLocalCap.BlockLengths() & aCaps.BlockLengths()); |
|
589 MatchingSub = (iLocalCap.Subbands() & aCaps.Subbands()); |
|
590 MatchingAlloc = (iLocalCap.AllocationMethods() & aCaps.AllocationMethods()); |
|
591 |
|
592 if ( MatchingFreq && |
|
593 MatchingChnl && |
|
594 MatchingBlck && |
|
595 MatchingSub && |
|
596 MatchingAlloc && |
|
597 ( iLocalCap.MinBitpoolValue() <= aCaps.MaxBitpoolValue() ) && |
|
598 ( iLocalCap.MaxBitpoolValue() >= aCaps.MinBitpoolValue() ) ) |
|
599 { |
|
600 TRACE_INFO((_L("CBTSACStreamerController::GetMatchingCaps() accessory configuration suits us"))) |
|
601 |
|
602 // Choose highest possible values that are supported |
|
603 |
|
604 // Sampling Frequency |
|
605 SetSamplingFrequency(aCaps, MatchingFreq); |
|
606 // Channel mode |
|
607 SetChannelMode(aCaps, MatchingChnl); |
|
608 // Blocks |
|
609 SetBlockLen(aCaps, MatchingBlck); |
|
610 // Subbands |
|
611 SetNumOfSubbands(aCaps, MatchingSub); |
|
612 // Allocation method |
|
613 SetAllocationMethod(aCaps, MatchingAlloc); |
|
614 // Bitpool |
|
615 SetBitpoolValues(aCaps); |
|
616 } |
|
617 else // no match |
|
618 { |
|
619 TRACE_INFO((_L("CBTSACStreamerController::GetMatchingCaps() **No Matching Capabilities**"))) |
|
620 ret = KErrNotFound; |
|
621 } |
|
622 return ret; |
|
623 } |
|
624 |
|
625 // ----------------------------------------------------------------------------- |
|
626 // CBTSACStreamerController::CheckAndAdjustBitpool |
|
627 // ----------------------------------------------------------------------------- |
|
628 // |
|
629 void CBTSACStreamerController::CheckAndAdjustBitpool(TSBCCodecCapabilities& aCap) |
|
630 { |
|
631 TRACE_FUNC |
|
632 // ******* Adjust bitpool if necessary ***** |
|
633 TInt targetbitrate; |
|
634 TInt nChnls = GetNumOfChannels(aCap); |
|
635 TInt nSbands = GetNumOfSubbands(aCap); |
|
636 TInt nBlck = GetBlockLen(aCap); |
|
637 TInt Freq = GetSamplingFrequency(aCap); |
|
638 TInt frameLength = FrameLengthFormula(aCap); |
|
639 // Note: this is the bitrate of the transmission. |
|
640 TInt bitrateInt = 8 * frameLength * Freq / nSbands / nBlck; |
|
641 |
|
642 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), nChnls = %d"), nChnls)) |
|
643 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), nSbands = %d"), nSbands)) |
|
644 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), nBlck = %d"), nBlck)) |
|
645 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), Freq = %d"), Freq)) |
|
646 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), MaxBP = %d"), aCap.MaxBitpoolValue())) |
|
647 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), Frame length = %d"), frameLength)) |
|
648 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), Bitrate = %d"), bitrateInt)) |
|
649 |
|
650 // max bit rate: 320kb/s for mono, |
|
651 // 512kb/s for two-channel modes |
|
652 if (aCap.ChannelModes() & EMono) |
|
653 { |
|
654 if (bitrateInt <= 320000.0) |
|
655 { |
|
656 targetbitrate = bitrateInt; |
|
657 } |
|
658 else // target bitrate=320kbps |
|
659 { |
|
660 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool() Adjusting..."))) |
|
661 targetbitrate = 320000.0; |
|
662 TInt BP = ( ((targetbitrate*nSbands*nBlck)/Freq) - 32 - (4*nSbands*nChnls) ) / (nBlck*nChnls); |
|
663 aCap.SetMaxBitpoolValue(BP); |
|
664 } |
|
665 } |
|
666 else |
|
667 { |
|
668 if (bitrateInt <= 512000.0) |
|
669 { |
|
670 targetbitrate = bitrateInt; |
|
671 } |
|
672 else // target bitrate=512kbps |
|
673 { |
|
674 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool() Adjusting..."))) |
|
675 targetbitrate = 512000.0; |
|
676 TInt BP = 0; |
|
677 if (aCap.ChannelModes() & EDualChannel) |
|
678 { |
|
679 BP = ( ((targetbitrate*nSbands*nBlck)/Freq) - 32 - (4*nSbands*nChnls) ) / (nBlck*nChnls); |
|
680 } |
|
681 else |
|
682 { |
|
683 TInt join = (aCap.ChannelModes() & EJointStereo) ? 1 : 0; |
|
684 BP = ( ((targetbitrate*nSbands*nBlck)/Freq) - 32 - (4*nSbands*nChnls) - (nSbands*join) ) / (nBlck); |
|
685 } |
|
686 |
|
687 aCap.SetMaxBitpoolValue(BP); |
|
688 // Calculate new frame length |
|
689 frameLength = FrameLengthFormula(aCap); |
|
690 } |
|
691 } |
|
692 |
|
693 iCurrentFrameLength = frameLength; |
|
694 iCurrentBitrate = targetbitrate; |
|
695 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), After Adjustment MaxBP: %d"), aCap.MaxBitpoolValue())) |
|
696 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), After Adjustment Frame length: %d"), iCurrentFrameLength)) |
|
697 TRACE_INFO((_L("CBTSACStreamerController::CheckAndAdjustBitpool(), After Adjustment Bitrate: %d"), iCurrentBitrate)) |
|
698 } |
|
699 |
|
700 // ----------------------------------------------------------------------------- |
|
701 // CBTSACStreamerController::RunL |
|
702 // ----------------------------------------------------------------------------- |
|
703 // |
|
704 void CBTSACStreamerController::RunL() |
|
705 { |
|
706 TRACE_FUNC |
|
707 switch(iStatus.Int()) |
|
708 { |
|
709 case KErrNone: |
|
710 { |
|
711 switch( iOngoingAction ) |
|
712 { |
|
713 case EErrorSending: |
|
714 { |
|
715 TRACE_INFO((_L("CBTSACStreamerController::RunL(), ErrorSending"))) |
|
716 |
|
717 TRACE_INFO((_L("CBTSACStreamerController::RunL(), TotalNbrOfDroppedPackets: %d"), iTotalNbrOfDroppedPackets)) |
|
718 TInt TotalNbrOfDroppedBits = iTotalNbrOfDroppedPackets*8; |
|
719 TRACE_INFO((_L("CBTSACStreamerController::RunL(), Total dropped bits: %d"), TotalNbrOfDroppedBits)) |
|
720 TRACE_INFO((_L("CBTSACStreamerController::RunL(), Current Bitrate: %d"), iCurrentBitrate)) |
|
721 TInt ReconfigureLimit = KLimitCheckInterval*iCurrentBitrate*KReconfigureLimitFactor; |
|
722 TRACE_INFO((_L("CBTSACStreamerController::RunL(), Limit for reconfigure : %d bits"), ReconfigureLimit)) |
|
723 TRACE_INFO((_L("CBTSACStreamerController::RunL(), PacketDropDeviation: %d (limit %d)"), iPacketDropDeviation, iCurrentBitpoolData->iMaxDeviation)) |
|
724 |
|
725 if((TotalNbrOfDroppedBits > ReconfigureLimit) && (iPacketDropDeviation >= iCurrentBitpoolData->iMaxDeviation)) |
|
726 { |
|
727 iPacketDropIoctl->Cancel(); |
|
728 |
|
729 if(iCurrentBitpoolData->iMinimumMaxBitpool) |
|
730 { |
|
731 TRACE_INFO((_L("CBTSACStreamerController::RunL(), Minimum max bitpool reached."))) |
|
732 TRACE_INFO((_L("CBTSACStreamerController::RunL(), Stop receive packet drops."))) |
|
733 return; |
|
734 } |
|
735 |
|
736 // Initialize values for upgrade timer. Only if setting min bitpool value fails, start retry timer. |
|
737 TInt delay = KStabilizationDelay; |
|
738 iOngoingAction = EStabilize; |
|
739 TInt err = ConfigureSEPBitpool(EDowngradeBitrate); |
|
740 if(err) |
|
741 { |
|
742 iOngoingAction = EDowngradeBitrate; |
|
743 delay = KRetryTimerDelay; |
|
744 } |
|
745 |
|
746 iTimer.After(iStatus, delay); |
|
747 SetActive(); |
|
748 } |
|
749 |
|
750 iPacketDropDeviation = 0; |
|
751 iTotalNbrOfDroppedPackets = 0; |
|
752 break; |
|
753 } |
|
754 |
|
755 case EStabilize: |
|
756 // Start receive overflow indications again |
|
757 TRACE_INFO((_L("CBTSACStreamerController::RunL(), stabilize timer expired."))) |
|
758 iPacketDropIoctl->Start(); |
|
759 break; |
|
760 |
|
761 case EDowngradeBitrate: |
|
762 case EUpgradeBitrate: |
|
763 case EStartStabilizingTimer: |
|
764 { |
|
765 TRACE_INFO((_L("CBTSACStreamerController::RunL(), Action = %d"), iOngoingAction)) |
|
766 TInt err = KErrNone; |
|
767 TInt delay = KStabilizationDelay; |
|
768 if(iOngoingAction != EStartStabilizingTimer) |
|
769 { |
|
770 err = ConfigureSEPBitpool(iOngoingAction); |
|
771 } |
|
772 if(err) |
|
773 { |
|
774 delay = KRetryTimerDelay; |
|
775 } |
|
776 else |
|
777 { |
|
778 TRACE_INFO((_L("CBTSACStreamerController::RunL(), stabilize timer started"))) |
|
779 iOngoingAction = EStabilize; |
|
780 } |
|
781 |
|
782 iTimer.After(iStatus, delay); |
|
783 SetActive(); |
|
784 break; |
|
785 } |
|
786 } |
|
787 break; |
|
788 } |
|
789 |
|
790 case KErrGeneral: // We have received error from audio adaptation |
|
791 { |
|
792 TRACE_INFO((_L("CBTSACStreamerController::RunL(), KErrGeneral"))) |
|
793 iAudioInput->Stop(); |
|
794 iAudioInput->Disconnect(); |
|
795 iObserver.NotifyError(KErrGeneral); |
|
796 break; |
|
797 } |
|
798 |
|
799 default: |
|
800 TRACE_INFO((_L("CBTSACStreamerController::RunL(), #default"))) |
|
801 break; |
|
802 } |
|
803 TRACE_INFO((_L("CBTSACStreamerController::RunL() completed"))) |
|
804 } |
|
805 |
|
806 // ----------------------------------------------------------------------------- |
|
807 // CBTSACStreamerController::DoCancel |
|
808 // ----------------------------------------------------------------------------- |
|
809 // |
|
810 void CBTSACStreamerController::DoCancel() |
|
811 { |
|
812 TRACE_FUNC |
|
813 iTimer.Cancel(); |
|
814 TRACE_INFO((_L("CBTSACStreamerController::DoCancel() completed"))) |
|
815 } |
|
816 |
|
817 // ----------------------------------------------------------------------------- |
|
818 // CBTSACStreamerController::RunError |
|
819 // ----------------------------------------------------------------------------- |
|
820 // |
|
821 TInt CBTSACStreamerController::RunError(TInt /*aError*/) |
|
822 { |
|
823 TRACE_FUNC |
|
824 return 0; |
|
825 } |
|
826 |
|
827 // ----------------------------------------------------------------------------- |
|
828 // CBTSACStreamerController::Error |
|
829 // ----------------------------------------------------------------------------- |
|
830 // |
|
831 TInt CBTSACStreamerController::Error(const TInt aError) |
|
832 { |
|
833 TRACE_INFO((_L("CBTSACStreamerController::Error() %d"), aError)) |
|
834 TInt ret = KErrNone; |
|
835 switch(aError) |
|
836 { |
|
837 case KErrOverflow: |
|
838 case KErrUnderflow: |
|
839 { |
|
840 DoSelfComplete(EErrorSending, KErrNone); |
|
841 break; |
|
842 } |
|
843 case KErrGeneral: |
|
844 { |
|
845 if(iState != EStateError) |
|
846 { |
|
847 iState = EStateError; |
|
848 DoSelfComplete(iOngoingAction, KErrGeneral); |
|
849 } |
|
850 break; |
|
851 } |
|
852 default: |
|
853 { |
|
854 ret = KErrUnknown; |
|
855 break; |
|
856 } |
|
857 } |
|
858 return ret; |
|
859 } |
|
860 |
|
861 // ----------------------------------------------------------------------------- |
|
862 // CBTSACStreamerController::GetCaps |
|
863 // ----------------------------------------------------------------------------- |
|
864 // |
|
865 TSBCCodecCapabilities& CBTSACStreamerController::GetCaps() |
|
866 { |
|
867 return iLocalCap; |
|
868 } |
|
869 |
|
870 // ----------------------------------------------------------------------------- |
|
871 // CBTSACStreamerController::SetBlockLen |
|
872 // ----------------------------------------------------------------------------- |
|
873 // |
|
874 void CBTSACStreamerController::SetBlockLen(TSBCCodecCapabilities& aCap, TUint8 aBlockLen) |
|
875 { |
|
876 // Set Block Lenght, select highest one |
|
877 if ( aBlockLen & EBlockLenSixteen ) |
|
878 { |
|
879 iEncoderCI->SetNumOfBlocks(TUint(16)); |
|
880 aCap.SetBlockLengths(EBlockLenSixteen); |
|
881 TRACE_INFO((_L("CBTSACStreamerController::SetBlockLen(), BlockLength: EBlockLenSixteen"))) |
|
882 } |
|
883 else if ( aBlockLen & EBlockLenTwelve ) |
|
884 { |
|
885 iEncoderCI->SetNumOfBlocks(TUint(12)); |
|
886 aCap.SetBlockLengths(EBlockLenTwelve); |
|
887 TRACE_INFO((_L("CBTSACStreamerController::SetBlockLen(), BlockLength: EBlockLenTwelve"))) |
|
888 } |
|
889 else if ( aBlockLen & EBlockLenEight ) |
|
890 { |
|
891 iEncoderCI->SetNumOfBlocks(TUint(8)); |
|
892 aCap.SetBlockLengths(EBlockLenEight); |
|
893 TRACE_INFO((_L("CBTSACStreamerController::SetBlockLen(), BlockLength: EBlockLenEight"))) |
|
894 } |
|
895 else if ( aBlockLen & EBlockLenFour ) |
|
896 { |
|
897 iEncoderCI->SetNumOfBlocks(TUint(4)); |
|
898 aCap.SetBlockLengths(EBlockLenFour); |
|
899 TRACE_INFO((_L("CBTSACStreamerController::SetBlockLen(), BlockLength: EBlockLenFour"))) |
|
900 } |
|
901 else |
|
902 { |
|
903 TRACE_INFO((_L("CBTSACStreamerController::SetBlockLen(), No matching Block Length"))) |
|
904 } |
|
905 } |
|
906 |
|
907 // ----------------------------------------------------------------------------- |
|
908 // CBTSACStreamerController::GetBlockLen |
|
909 // ----------------------------------------------------------------------------- |
|
910 // |
|
911 TInt CBTSACStreamerController::GetBlockLen(TSBCCodecCapabilities& aCap) const |
|
912 { |
|
913 TInt nBlck = 0; |
|
914 switch( aCap.BlockLengths() ) |
|
915 { |
|
916 case EBlockLenSixteen: |
|
917 nBlck = 16; |
|
918 break; |
|
919 case EBlockLenTwelve: |
|
920 nBlck = 12; |
|
921 break; |
|
922 case EBlockLenEight: |
|
923 nBlck = 8; |
|
924 break; |
|
925 case EBlockLenFour: |
|
926 nBlck = 4; |
|
927 break; |
|
928 default: |
|
929 TRACE_INFO((_L("CBTSACStreamerController::GetBlockLen(), #default"))) |
|
930 nBlck = 16; |
|
931 break; |
|
932 } |
|
933 return nBlck; |
|
934 } |
|
935 |
|
936 // ----------------------------------------------------------------------------- |
|
937 // CBTSACStreamerController::SetBitpoolValues |
|
938 // ----------------------------------------------------------------------------- |
|
939 // |
|
940 void CBTSACStreamerController::SetBitpoolValues(TSBCCodecCapabilities& aCap) |
|
941 { |
|
942 // Define max bitpool |
|
943 TInt MaxBP = 0; |
|
944 TBool ProperMaxBitpoolFound = EFalse; |
|
945 for(TInt i = 0 ; i < KNumOfBitpoolValues ; i++) |
|
946 { |
|
947 if(aCap.MaxBitpoolValue() >= KMaxBitpoolValues[i]) |
|
948 { |
|
949 MaxBP = KMaxBitpoolValues[i]; |
|
950 ProperMaxBitpoolFound = ETrue; |
|
951 break; |
|
952 } |
|
953 } |
|
954 if(!ProperMaxBitpoolFound) |
|
955 { |
|
956 // None of our proposed max bitpool values weren't suitable for accessory. |
|
957 // Let's use the one which was proposed by the accessory. |
|
958 MaxBP = aCap.MaxBitpoolValue(); |
|
959 } |
|
960 |
|
961 // Define min bitpool. This bitpool value is negotiated with sink. |
|
962 TInt MinBP = (iLocalCap.MinBitpoolValue() < aCap.MinBitpoolValue()) ? aCap.MinBitpoolValue() : iLocalCap.MinBitpoolValue(); |
|
963 |
|
964 // Define bitpool which is used for medium quality streaming (when streaming is interfered for some reason). |
|
965 // This is real lowest bitpool value which is used for streaming. |
|
966 |
|
967 // Check if selected max bitpool value is smaller than our default min bitpool value, if it is, set |
|
968 // minimum max bitpool value to be same as max value otherwise just update it with our default min value. |
|
969 if(MaxBP < MAXBITPOOLVALUEMIN) |
|
970 { |
|
971 // Update the minumum bitpool data |
|
972 iBitpoolData[iBitpoolData.Count()-1].iMaxBitpoolValue = MaxBP; |
|
973 } |
|
974 else if(MAXBITPOOLVALUEMIN < MinBP) // Check also that minimum max bitpool value is not smaller than bitpool which is negotiated for the link. |
|
975 { |
|
976 iBitpoolData[iBitpoolData.Count()-1].iMaxBitpoolValue = MinBP; |
|
977 } |
|
978 |
|
979 TRACE_INFO((_L("CBTSACStreamerController::SetBitpoolValues(), Remote Max Bitpool: %d"), aCap.MaxBitpoolValue())) |
|
980 TRACE_INFO((_L("CBTSACStreamerController::SetBitpoolValues(), Remote Min Bitpool: %d"), aCap.MinBitpoolValue())) |
|
981 |
|
982 aCap.SetMaxBitpoolValue(MaxBP); |
|
983 TRACE_INFO((_L("CBTSACStreamerController::SetBitpoolValues(), Max Bitpool: %d"), MaxBP)) |
|
984 aCap.SetMinBitpoolValue(MinBP); |
|
985 TRACE_INFO((_L("CBTSACStreamerController::SetBitpoolValues(), Min Bitpool: %d"), MinBP)) |
|
986 } |
|
987 |
|
988 // ----------------------------------------------------------------------------- |
|
989 // CBTSACStreamerController::SetAllocationMethod |
|
990 // ----------------------------------------------------------------------------- |
|
991 // |
|
992 void CBTSACStreamerController::SetAllocationMethod(TSBCCodecCapabilities& aCap, TUint8 aAllocationMethod) |
|
993 { |
|
994 // Set Allocation Method, select highest one |
|
995 if ( aAllocationMethod & ELoudness ) |
|
996 { |
|
997 iEncoderCI->SetAllocationMethod(CSbcEncoderIntfc::ESbcAllocationLoudness); |
|
998 aCap.SetAllocationMethods(ELoudness); |
|
999 TRACE_INFO((_L("CBTSACStreamerController::SetAllocationMethod(), AllocationMethod: ELoudness"))) |
|
1000 } |
|
1001 else if ( aAllocationMethod & ESNR ) |
|
1002 { |
|
1003 iEncoderCI->SetAllocationMethod(CSbcEncoderIntfc::ESbcAllocationSNR); |
|
1004 aCap.SetAllocationMethods(ESNR); |
|
1005 TRACE_INFO((_L("CBTSACStreamerController::SetAllocationMethod(), AllocationMethod: ESNR"))) |
|
1006 } |
|
1007 else |
|
1008 { |
|
1009 TRACE_INFO((_L("CBTSACStreamerController::SetAllocationMethod(), No matching Allocation Method"))) |
|
1010 } |
|
1011 } |
|
1012 // ----------------------------------------------------------------------------- |
|
1013 // CBTSACStreamerController::SetChannelMode |
|
1014 // ----------------------------------------------------------------------------- |
|
1015 // |
|
1016 void CBTSACStreamerController::SetChannelMode(TSBCCodecCapabilities& aCap, TUint8 aChannelMode) |
|
1017 { |
|
1018 // Set Channel mode, select highest one |
|
1019 if ( aChannelMode & EJointStereo ) |
|
1020 { |
|
1021 iEncoderCI->SetChannelMode(CSbcEncoderIntfc::ESbcChannelJointStereo); |
|
1022 aCap.SetChannelModes(EJointStereo); |
|
1023 TRACE_INFO((_L("CBTSACStreamerController::SetChannelMode(), ChannelMode: EJointStereo"))) |
|
1024 } |
|
1025 else if ( aChannelMode & EStereo ) |
|
1026 { |
|
1027 iEncoderCI->SetChannelMode(CSbcEncoderIntfc::ESbcChannelStereo); |
|
1028 aCap.SetChannelModes(EStereo); |
|
1029 TRACE_INFO((_L("CBTSACStreamerController::SetChannelMode(), ChannelMode: EStereo"))) |
|
1030 } |
|
1031 else if ( aChannelMode & EDualChannel ) |
|
1032 { |
|
1033 iEncoderCI->SetChannelMode(CSbcEncoderIntfc::ESbcChannelDual); |
|
1034 aCap.SetChannelModes(EDualChannel); |
|
1035 TRACE_INFO((_L("CBTSACStreamerController::SetChannelMode(), ChannelMode: EDualChannel"))) |
|
1036 } |
|
1037 else if ( aChannelMode & EMono ) |
|
1038 { |
|
1039 iEncoderCI->SetChannelMode(CSbcEncoderIntfc::ESbcChannelMono); |
|
1040 aCap.SetChannelModes(EMono); |
|
1041 TRACE_INFO((_L("CBTSACStreamerController::SetChannelMode(), ChannelMode: EMono"))) |
|
1042 } |
|
1043 else |
|
1044 { |
|
1045 TRACE_INFO((_L("CBTSACStreamerController::SetChannelMode(), No matching Channel Mode"))) |
|
1046 } |
|
1047 } |
|
1048 |
|
1049 // ----------------------------------------------------------------------------- |
|
1050 // CBTSACStreamerController::SetSamplingFrequency |
|
1051 // ----------------------------------------------------------------------------- |
|
1052 // |
|
1053 void CBTSACStreamerController::SetSamplingFrequency(TSBCCodecCapabilities& aCap, TUint8 aFrequency) |
|
1054 { |
|
1055 // Set Sampling Frequency, select highest one |
|
1056 if ( aFrequency & E48kHz ) |
|
1057 { |
|
1058 iEncoderCI->SetSamplingFrequency(TUint(48000)); |
|
1059 aCap.SetSamplingFrequencies(E48kHz); |
|
1060 TRACE_INFO((_L("CBTSACStreamerController::SetSamplingFrequency(), Sampling Frequency: E48kHz"))) |
|
1061 } |
|
1062 else if ( aFrequency & E44100Hz ) |
|
1063 { |
|
1064 iEncoderCI->SetSamplingFrequency(TUint(44100)); |
|
1065 aCap.SetSamplingFrequencies(E44100Hz); |
|
1066 TRACE_INFO((_L("CBTSACStreamerController::SetSamplingFrequency(), Sampling Frequency: E44100Hz"))) |
|
1067 } |
|
1068 else if ( aFrequency & E32kHz ) |
|
1069 { |
|
1070 iEncoderCI->SetSamplingFrequency(TUint(32000)); |
|
1071 aCap.SetSamplingFrequencies(E32kHz); |
|
1072 TRACE_INFO((_L("CBTSACStreamerController::SetSamplingFrequency(), Sampling Frequency: E32kHz"))) |
|
1073 } |
|
1074 else if ( aFrequency & E16kHz ) |
|
1075 { |
|
1076 iEncoderCI->SetSamplingFrequency(TUint(16000)); |
|
1077 aCap.SetSamplingFrequencies(E16kHz); |
|
1078 TRACE_INFO((_L("CBTSACStreamerController::SetSamplingFrequency(), Sampling Frequency: E16kHz"))) |
|
1079 } |
|
1080 else |
|
1081 { |
|
1082 TRACE_INFO((_L("CBTSACStreamerController::SetSamplingFrequency(), No matching Sampling Frequency"))) |
|
1083 } |
|
1084 } |
|
1085 |
|
1086 // ----------------------------------------------------------------------------- |
|
1087 // CBTSACStreamerController::GetSamplingFrequency |
|
1088 // ----------------------------------------------------------------------------- |
|
1089 // |
|
1090 TInt CBTSACStreamerController::GetSamplingFrequency(TSBCCodecCapabilities& aCap) const |
|
1091 { |
|
1092 TInt Freq = 0; |
|
1093 switch( aCap.SamplingFrequencies() ) |
|
1094 { |
|
1095 case E48kHz: |
|
1096 Freq = 48000; |
|
1097 break; |
|
1098 case E44100Hz: |
|
1099 Freq = 44100; |
|
1100 break; |
|
1101 case E32kHz: |
|
1102 Freq = 32000; |
|
1103 break; |
|
1104 case E16kHz: |
|
1105 Freq = 16000; |
|
1106 break; |
|
1107 default: |
|
1108 TRACE_INFO((_L("CBTSACStreamerController::GetSamplingFrequency(), #default"))) |
|
1109 Freq = 48000; |
|
1110 break; |
|
1111 } |
|
1112 return Freq; |
|
1113 } |
|
1114 |
|
1115 // ----------------------------------------------------------------------------- |
|
1116 // CBTSACStreamerController::GetNumOfChannels |
|
1117 // ----------------------------------------------------------------------------- |
|
1118 // |
|
1119 TInt CBTSACStreamerController::GetNumOfChannels(TSBCCodecCapabilities& aCap) const |
|
1120 { |
|
1121 TInt nChnls = (aCap.ChannelModes() & EMono) ? 1 : 2; |
|
1122 return nChnls; |
|
1123 } |
|
1124 |
|
1125 // ----------------------------------------------------------------------------- |
|
1126 // CBTSACStreamerController::SetNumOfSubbands |
|
1127 // ----------------------------------------------------------------------------- |
|
1128 // |
|
1129 void CBTSACStreamerController::SetNumOfSubbands(TSBCCodecCapabilities& aCap, TUint8 aNumOfSubbands) |
|
1130 { |
|
1131 // Set Number of Subbands, select highest one |
|
1132 if ( aNumOfSubbands & EEightSubbands ) |
|
1133 { |
|
1134 iEncoderCI->SetNumOfSubbands(TUint(8)); |
|
1135 aCap.SetSubbands(EEightSubbands); |
|
1136 TRACE_INFO((_L("CBTSACStreamerController::SetNumOfSubbands(), Subband: EEightSubbands"))) |
|
1137 } |
|
1138 else if ( aNumOfSubbands & EFourSubbands ) |
|
1139 { |
|
1140 iEncoderCI->SetNumOfSubbands(TUint(4)); |
|
1141 aCap.SetSubbands(EFourSubbands); |
|
1142 TRACE_INFO((_L("CBTSACStreamerController::SetNumOfSubbands(), Subband: EFourSubbands"))) |
|
1143 } |
|
1144 else |
|
1145 { |
|
1146 TRACE_INFO((_L("CBTSACStreamerController::SetNumOfSubbands(), No matching Subband"))) |
|
1147 } |
|
1148 } |
|
1149 |
|
1150 // ----------------------------------------------------------------------------- |
|
1151 // CBTSACStreamerController::GetNumOfSubbands |
|
1152 // ----------------------------------------------------------------------------- |
|
1153 // |
|
1154 TInt CBTSACStreamerController::GetNumOfSubbands(TSBCCodecCapabilities& aCap) const |
|
1155 { |
|
1156 TInt nSbands = (aCap.Subbands() & EEightSubbands) ? 8 : 4; |
|
1157 return nSbands; |
|
1158 } |
|
1159 |
|
1160 // ----------------------------------------------------------------------------- |
|
1161 // CBTSACStreamerController::FrameLengthFormula |
|
1162 // ----------------------------------------------------------------------------- |
|
1163 // |
|
1164 TInt CBTSACStreamerController::FrameLengthFormula(TSBCCodecCapabilities& aCap) const |
|
1165 { |
|
1166 TInt join = ( aCap.ChannelModes() & EJointStereo ) ? 1 : 0; |
|
1167 TInt nChnls = GetNumOfChannels(aCap); |
|
1168 TInt nSbands = GetNumOfSubbands(aCap); |
|
1169 TInt nBlck = GetBlockLen(aCap); |
|
1170 |
|
1171 // For mono (and dual channel) mode the formula is slightly differend than for stereo mode(s). |
|
1172 TInt frameLength = |
|
1173 ( (aCap.ChannelModes() & EMono) || (aCap.ChannelModes() & EDualChannel) ) ? |
|
1174 4 + ((4 * nSbands * nChnls) / 8) + ( (nBlck * nChnls * aCap.MaxBitpoolValue()) / 8): |
|
1175 4 + ((4 * nSbands * nChnls) / 8) + ( (join * nSbands + nBlck * aCap.MaxBitpoolValue()) / 8)/* + join*/; |
|
1176 |
|
1177 // Note: last "+ join" in latter version of the formula is for joint stereo. |
|
1178 // Otherwise the formula doesn't calculate the extra byte that's in the header. |
|
1179 return frameLength; |
|
1180 } |
|
1181 |
|
1182 // ----------------------------------------------------------------------------- |
|
1183 // CBTSACStreamerController::PacketsDropped |
|
1184 // ----------------------------------------------------------------------------- |
|
1185 // |
|
1186 void CBTSACStreamerController::PacketsDropped(TInt aError) |
|
1187 { |
|
1188 TRACE_FUNC |
|
1189 if(!iTotalNbrOfDroppedPackets) |
|
1190 { |
|
1191 // This is first packet drop indication after previous sample interval |
|
1192 iFirstPacketDropTime.UniversalTime(); |
|
1193 } |
|
1194 TTime timeNow; |
|
1195 timeNow.UniversalTime(); |
|
1196 iPacketDropDeviation = static_cast<TInt32>(timeNow.MicroSecondsFrom(iFirstPacketDropTime).Int64()); |
|
1197 |
|
1198 iTotalNbrOfDroppedPackets += aError; |
|
1199 |
|
1200 if(!IsActive()) |
|
1201 { |
|
1202 iOngoingAction = EErrorSending; |
|
1203 iTimer.After(iStatus, KDataCollectDelay); |
|
1204 SetActive(); |
|
1205 } |
|
1206 } |
|
1207 |
|
1208 // ----------------------------------------------------------------------------- |
|
1209 // CBTSACStreamerController::SetCurrentBitpoolData |
|
1210 // ----------------------------------------------------------------------------- |
|
1211 // |
|
1212 TInt CBTSACStreamerController::SetCurrentBitpoolData(TInt aBitpool) |
|
1213 { |
|
1214 TRACE_FUNC |
|
1215 TInt err = KErrNone; |
|
1216 TInt Index = GetIndex(aBitpool); |
|
1217 if(Index >= 0) |
|
1218 { |
|
1219 iCurrentBitpoolData = GetBitpoolData(Index); |
|
1220 } |
|
1221 else |
|
1222 { |
|
1223 err = KErrNotFound; |
|
1224 } |
|
1225 return err; |
|
1226 } |
|
1227 // ----------------------------------------------------------------------------- |
|
1228 // CBTSACStreamerController::GetIndex |
|
1229 // ----------------------------------------------------------------------------- |
|
1230 // |
|
1231 TInt CBTSACStreamerController::GetIndex(TInt aBitpool) |
|
1232 { |
|
1233 TInt Bitpool = aBitpool; |
|
1234 if(aBitpool > iMatchCap.MaxBitpoolValue()) |
|
1235 { |
|
1236 Bitpool = iMatchCap.MaxBitpoolValue(); |
|
1237 } |
|
1238 for(TInt i = 0 ; i < iBitpoolData.Count() ; i++) |
|
1239 { |
|
1240 if(Bitpool == iBitpoolData[i].iMaxBitpoolValue) |
|
1241 { |
|
1242 return i; |
|
1243 } |
|
1244 } |
|
1245 return KErrNotFound; |
|
1246 } |
|
1247 |
|
1248 // ----------------------------------------------------------------------------- |
|
1249 // CBTSACStreamerController::IndexValid |
|
1250 // ----------------------------------------------------------------------------- |
|
1251 // |
|
1252 TBool CBTSACStreamerController::IndexValid(TInt aIndex) |
|
1253 { |
|
1254 if(aIndex >= 0 && aIndex < iBitpoolData.Count()) |
|
1255 return ETrue; |
|
1256 else |
|
1257 return EFalse; |
|
1258 } |
|
1259 |
|
1260 // ----------------------------------------------------------------------------- |
|
1261 // CBTSACStreamerController::InitializeBitpoolData |
|
1262 // ----------------------------------------------------------------------------- |
|
1263 // |
|
1264 void CBTSACStreamerController::InitializeBitpoolDataL() |
|
1265 { |
|
1266 TRACE_FUNC |
|
1267 TBitpoolData data; |
|
1268 iBitpoolData.Reset(); |
|
1269 for(TInt i = 0 ; i < KNumOfBitpoolValues ; i++) |
|
1270 { |
|
1271 data.iMaxBitpoolValue = KMaxBitpoolValues[i]; |
|
1272 data.iMaxDeviation = KDeviationValues[i]; |
|
1273 //data.iUpgradeDelay = KUpgradeDelays[i]; |
|
1274 data.iUpBitpoolIndex = (i == 0) ? i : i - 1; |
|
1275 data.iIndex = i; |
|
1276 data.iDownBitpoolIndex = (i == KNumOfBitpoolValues - 1) ? i : i + 1; |
|
1277 data.iMinimumMaxBitpool = (i == KNumOfBitpoolValues - 1) ? ETrue : EFalse; |
|
1278 iBitpoolData.AppendL(data); |
|
1279 } |
|
1280 } |
|
1281 |
|
1282 // ----------------------------------------------------------------------------- |
|
1283 // CBTSACStreamerController::GetBitpoolData |
|
1284 // ----------------------------------------------------------------------------- |
|
1285 // |
|
1286 TBitpoolData* CBTSACStreamerController::GetBitpoolData(TInt aIndex) |
|
1287 { |
|
1288 if(aIndex < 0 || aIndex >= iBitpoolData.Count()) |
|
1289 return NULL; |
|
1290 |
|
1291 return &iBitpoolData[aIndex]; |
|
1292 } |
|
1293 |
|
1294 // ----------------------------------------------------------------------------- |
|
1295 // CBTSACStreamerController::ReorganizeBitpoolTable |
|
1296 // ----------------------------------------------------------------------------- |
|
1297 // |
|
1298 void CBTSACStreamerController::ReorganizeBitpoolTable(TInt aNegotiatedMaxBitpool) |
|
1299 { |
|
1300 TRACE_INFO((_L("CBTSACStreamerController::ReorganizeBitpoolTable(), Negotiated Max Bitpool %d"), aNegotiatedMaxBitpool)) |
|
1301 // Start checking from the lowest possible bitpool value |
|
1302 for(TInt i = (KNumOfBitpoolValues - 1) ; i > 0 ; i--) |
|
1303 { |
|
1304 if(aNegotiatedMaxBitpool <= KMaxBitpoolValues[i]) |
|
1305 { |
|
1306 TInt ii; |
|
1307 for(ii = 0 ; ii < i ; ii++) |
|
1308 { |
|
1309 iBitpoolData.Remove(0); |
|
1310 } |
|
1311 TRACE_INFO((_L("CBTSACStreamerController::ReorganizeBitpoolTable(), Tables removed: %d"), ii)) |
|
1312 for(TInt j = 0 ; j < iBitpoolData.Count() ; j++) |
|
1313 { |
|
1314 if(j == 0) |
|
1315 { |
|
1316 iBitpoolData[j].iMaxBitpoolValue = aNegotiatedMaxBitpool; |
|
1317 } |
|
1318 iBitpoolData[j].iIndex = j; |
|
1319 iBitpoolData[j].iUpBitpoolIndex = (j == 0) ? j : j - 1; |
|
1320 iBitpoolData[j].iDownBitpoolIndex = (j == iBitpoolData.Count() - 1) ? j : j + 1; |
|
1321 } |
|
1322 break; |
|
1323 } |
|
1324 } |
|
1325 TRACE_INFO((_L("CBTSACStreamerController::ReorganizeBitpoolTable(), Tables left: %d"), iBitpoolData.Count())) |
|
1326 for(TInt k = 0 ; k < iBitpoolData.Count() ; k++) |
|
1327 { |
|
1328 TRACE_INFO((_L("CBTSACStreamerController::ReorganizeBitpoolTable(), Table[%d] MaxBP: %d"), k, iBitpoolData[k].iMaxBitpoolValue)) |
|
1329 } |
|
1330 } |
|
1331 |
|
1332 // ----------------------------------------------------------------------------- |
|
1333 // CBTSACStreamerController::DoSelfComplete |
|
1334 // ----------------------------------------------------------------------------- |
|
1335 // |
|
1336 void CBTSACStreamerController::DoSelfComplete(EOngoingAction aAction, TInt aError) |
|
1337 { |
|
1338 TRACE_FUNC |
|
1339 if (IsActive()) |
|
1340 { |
|
1341 // Stop timer |
|
1342 Cancel(); |
|
1343 } |
|
1344 if (!IsActive()) |
|
1345 { |
|
1346 // Just self complete here, handle error in RunL |
|
1347 iOngoingAction = aAction; |
|
1348 TRequestStatus *status = &iStatus; |
|
1349 iStatus = KRequestPending; |
|
1350 iThread.RequestComplete(status, aError); |
|
1351 SetActive(); |
|
1352 } |
|
1353 else |
|
1354 { |
|
1355 TRACE_INFO((_L("CBTSACStreamerController::DoSelfComplete((), Couldn't do self complete"))) |
|
1356 } |
|
1357 } |
|
1358 // End of File |