mmfenh/advancedaudiocontroller/audiocontrollerpluginsvariant/AdvancedAudioController/Src/AdvancedAudioRecordController.cpp
changeset 0 71ca22bcf22a
child 12 2eb3b066cc7d
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 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:  This file contains the base class from which specific audio
       
    15 *                record controllers are derived. This class encapsulates common
       
    16 *                behavior for all audio record controllers.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include	"AdvancedAudioRecordController.h"
       
    24 #include 	"AdvancedAudioResource.h"
       
    25 #include 	"AdvancedAudioUtility.h"
       
    26 #include 	<mmffile.h>
       
    27 #include 	<sysutil.h>
       
    28 
       
    29 // CONSTANTS
       
    30 const TUint KDefineIOBufferSize = 512;
       
    31 
       
    32 // ============================ MEMBER FUNCTIONS ===============================
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // CAdvancedAudioRecordController::CAdvancedAudioRecordController
       
    36 // C++ default constructor can NOT contain any code, that might leave.
       
    37 // -----------------------------------------------------------------------------
       
    38 //
       
    39 EXPORT_C CAdvancedAudioRecordController::CAdvancedAudioRecordController()
       
    40 	:	iState(EStopped),
       
    41 		iAudioInput(NULL),
       
    42 		iAudioResource(NULL),
       
    43 		iAudioUtility(NULL),
       
    44 		iSinkWritePosition(0),
       
    45 		iMaxFileSize(-1)
       
    46     {
       
    47     RThread().SetPriority(EPriorityRealTime);
       
    48     }
       
    49 
       
    50 EXPORT_C void CAdvancedAudioRecordController::ConstructL()
       
    51 	{
       
    52 	CAdvancedAudioController::ConstructL();
       
    53 
       
    54     // Construct custom command parsers
       
    55     CMMFAudioRecordDeviceCustomCommandParser* audRecDevParser = CMMFAudioRecordDeviceCustomCommandParser::NewL(*this);
       
    56     CleanupStack::PushL(audRecDevParser);
       
    57     AddCustomCommandParserL(*audRecDevParser);
       
    58     CleanupStack::Pop(audRecDevParser);
       
    59 
       
    60     CMMFAudioRecordControllerCustomCommandParser* audRecConParser = CMMFAudioRecordControllerCustomCommandParser::NewL(*this);
       
    61     CleanupStack::PushL(audRecConParser);
       
    62     AddCustomCommandParserL(*audRecConParser);
       
    63     CleanupStack::Pop(audRecConParser);
       
    64 	}
       
    65 
       
    66 // Destructor
       
    67 EXPORT_C CAdvancedAudioRecordController::~CAdvancedAudioRecordController()
       
    68     {
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CAdvancedAudioRecordController::DoStopL
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 EXPORT_C void CAdvancedAudioRecordController::DoStopL()
       
    76     {
       
    77     iAudioInput->StopL(); 	// This might call EmptySharedBufferL
       
    78 
       
    79     //Check the Sink is Valid since it might have been set to NULL
       
    80     // because of an Out of Memory Situation
       
    81 
       
    82     if(iDataSink)
       
    83     	iDataSink->SinkStopL();
       
    84     iTimePositionInMicroSecs = iDuration;
       
    85     iState = EStopped;
       
    86     }
       
    87 
       
    88 // -----------------------------------------------------------------------------
       
    89 // CAdvancedAudioRecordController::WriteIfEnoughSpaceL
       
    90 //
       
    91 // Writes data starting from aWritePosition in iBuffer.
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 EXPORT_C void CAdvancedAudioRecordController::WriteIfEnoughSpaceL(
       
    95 	CMMFBuffer* aBuffer,
       
    96 	TInt aWritePosition,
       
    97 	MDataSource* aSupplier,
       
    98 	TInt aWriteLen )
       
    99     {
       
   100 #ifdef _DEBUG
       
   101 	RDebug::Print(_L("CAdvancedAudioRecordController::WriteIfEnoughSpaceL"));
       
   102 #endif
       
   103 
       
   104     //Using the outstanding position for determining the correct current write position
       
   105     TInt writePosition = aWritePosition+iOutstandingPos;
       
   106     if ( SysUtil::DiskSpaceBelowCriticalLevelL(NULL, aBuffer->BufferSize(), iDriveNumber) )
       
   107         {
       
   108 		iDataSink->SinkStopL();
       
   109         iDataSink = NULL;
       
   110         User::Leave(KErrDiskFull);
       
   111         }
       
   112 
       
   113     if ( aWriteLen && aSupplier )
       
   114         {
       
   115         aBuffer->SetStatus(EBeingEmptied);
       
   116         static_cast <CMMFClip*>(iDataSink)->WriteBufferL(aWriteLen, aBuffer, writePosition, aSupplier);
       
   117         }
       
   118     else if ( aSupplier )
       
   119         {
       
   120         aBuffer->SetStatus(EBeingEmptied);
       
   121         static_cast <CMMFClip*>(iDataSink)->WriteBufferL(aBuffer, writePosition, aSupplier);
       
   122         }
       
   123     else
       
   124         {
       
   125         aBuffer->SetStatus(EBeingEmptied);
       
   126         static_cast <CMMFClip*>(iDataSink)->WriteBufferL(aBuffer, writePosition);
       
   127         // Use EUnAvailable since EAvailable changes the buffer size to 0
       
   128         aBuffer->SetStatus(EUnAvailable);
       
   129         }
       
   130     //Update outstanding write position
       
   131     if (aBuffer->Status() == EBeingEmptied)   // Async request
       
   132         iOutstandingPos += aBuffer->BufferSize();
       
   133     }
       
   134 
       
   135 // -----------------------------------------------------------------------------
       
   136 // CAdvancedAudioRecordController::WriteIfMaxFileSizeReachedL
       
   137 // -----------------------------------------------------------------------------
       
   138 //
       
   139 EXPORT_C void CAdvancedAudioRecordController::WriteIfMaxFileSizeReachedL(
       
   140 	CMMFBuffer* aBuffer )
       
   141     {
       
   142 #ifdef _DEBUG
       
   143     RDebug::Print(_L("CAdvancedAudioRecordController::WriteIfMaxFileSizeReachedL"));
       
   144 #endif
       
   145     TInt maxWriteLen = iMaxFileSize - iSinkWritePosition;
       
   146     TInt scanLen = 0, frameLen = 0, writeLen = 0;
       
   147     TDes8& aBufDes = static_cast <CMMFDataBuffer*> (aBuffer)->Data();
       
   148 
       
   149     if ( iSinkWritePosition )
       
   150         {
       
   151         maxWriteLen = iMaxFileSize - iSinkWritePosition;
       
   152         }
       
   153     else
       
   154         {
       
   155         maxWriteLen = iMaxFileSize - iAudioUtility->HeaderOffset();
       
   156         }
       
   157 
       
   158     TInt seekOffset = iAudioUtility->SeekSync(static_cast <CMMFDataBuffer*> (aBuffer),
       
   159                                          aBufDes.Size());
       
   160 
       
   161     if ( seekOffset >= maxWriteLen )
       
   162         {
       
   163 #ifdef _DEBUG
       
   164     RDebug::Print(_L("Wrote %d bytes..."), writeLen);
       
   165 #endif
       
   166         User::Leave(KErrCompletion);
       
   167         }
       
   168 
       
   169     scanLen = seekOffset;
       
   170 
       
   171     while ( scanLen <= maxWriteLen )
       
   172 		{
       
   173         writeLen = scanLen;
       
   174 
       
   175         TAudioFrameInfo frameInfo;
       
   176         frameLen = iAudioUtility->FrameInfo(aBufDes.Ptr() + scanLen,
       
   177                                        aBufDes.Size() - scanLen, frameInfo);
       
   178         if ( !frameLen )
       
   179             {
       
   180             break;
       
   181             }
       
   182         scanLen += frameLen;
       
   183         }
       
   184 
       
   185     if ( writeLen )
       
   186         {
       
   187         CMMFDataBuffer* buf = CreateSourceBufferOfSizeLC(writeLen);
       
   188         static_cast <CMMFDataBuffer*>(buf)->Data().Copy(aBufDes.Ptr(), writeLen);
       
   189         WriteIfEnoughSpaceL(buf, iSinkWritePosition, NULL, writeLen); // Synchronous write
       
   190         BufferEmptiedL(buf);
       
   191         CleanupStack::PopAndDestroy(buf);
       
   192         }
       
   193 
       
   194 #ifdef _DEBUG
       
   195     RDebug::Print(_L("Wrote %d bytes..."), writeLen);
       
   196 #endif
       
   197     User::Leave(KErrCompletion);
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CAdvancedAudioRecordController::AddDataSourceL
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 EXPORT_C void CAdvancedAudioRecordController::AddDataSourceL(
       
   205 	MDataSource& aSource )
       
   206     {
       
   207 #ifdef _DEBUG
       
   208 	RDebug::Print(_L("CAdvancedAudioRecordController::AddDataSourceL"));
       
   209 #endif
       
   210 
       
   211     if ( iDataSource )
       
   212     	{
       
   213         User::Leave(KErrAlreadyExists);
       
   214 		}
       
   215 
       
   216     if ( aSource.DataSourceType() == KUidMmfAudioInput )
       
   217         {
       
   218 		iDataSource = &aSource;
       
   219 		DoAddDataSourceL();
       
   220 		}
       
   221     else
       
   222         {
       
   223         User::Leave(KErrNotSupported);
       
   224         }
       
   225     }
       
   226 
       
   227 // -----------------------------------------------------------------------------
       
   228 // CAdvancedAudioRecordController::AddDataSinkL
       
   229 // -----------------------------------------------------------------------------
       
   230 //
       
   231 EXPORT_C void CAdvancedAudioRecordController::AddDataSinkL(
       
   232 	MDataSink& aSink )
       
   233     {
       
   234 #ifdef _DEBUG
       
   235 	RDebug::Print(_L("CAdvancedAudioRecordController::AddDataSinkL"));
       
   236 #endif
       
   237     if ( iDataSink )
       
   238     	{
       
   239         User::Leave(KErrAlreadyExists);
       
   240 		}
       
   241 
       
   242     if ( aSink.DataSinkType() == KUidMmfFileSink )
       
   243         {
       
   244         iDataSink = &aSink;
       
   245 //        iDataSink->SinkPrimeL();
       
   246 //        iDataSink->SinkThreadLogon(*this);
       
   247 //		iDriveNumber = iAudioUtility->GetDriveNumber(static_cast <CMMFFile*> (iDataSink)->FileDrive());
       
   248         TRAPD(err, DoAddDataSinkL());
       
   249 
       
   250         if (err)
       
   251         	{
       
   252 			if(iDataSink)
       
   253 			{
       
   254 				iDataSink->SinkStopL();
       
   255 	        	iDataSink = NULL;
       
   256         	}
       
   257         	User::Leave(err);
       
   258         	}
       
   259         }
       
   260      else
       
   261         {
       
   262         User::Leave(KErrNotSupported);
       
   263         }
       
   264     }
       
   265 
       
   266 // -----------------------------------------------------------------------------
       
   267 // CAdvancedAudioRecordController::RemoveDataSourceL
       
   268 // -----------------------------------------------------------------------------
       
   269 //
       
   270 EXPORT_C void CAdvancedAudioRecordController::RemoveDataSourceL(
       
   271 	MDataSource& aDataSource )
       
   272     {
       
   273 #ifdef _DEBUG
       
   274 	RDebug::Print(_L("CAdvancedAudioRecordController::RemoveDataSourceL"));
       
   275 #endif
       
   276 	if ( !iDataSource )
       
   277 		{
       
   278         User::Leave(KErrNotReady);
       
   279 		}
       
   280 
       
   281     if ( iDataSource != &aDataSource )
       
   282     	{
       
   283         User::Leave(KErrArgument);
       
   284 		}
       
   285 
       
   286     if ( iState == ERecording )
       
   287     	{
       
   288         User::Leave(KErrNotReady);
       
   289 		}
       
   290 
       
   291 	delete iAudioInput;
       
   292 	iAudioInput = NULL;
       
   293     iDataSource = NULL;
       
   294     }
       
   295 
       
   296 // -----------------------------------------------------------------------------
       
   297 // CAdvancedAudioRecordController::RemoveDataSinkL
       
   298 // -----------------------------------------------------------------------------
       
   299 //
       
   300 EXPORT_C void CAdvancedAudioRecordController::RemoveDataSinkL(
       
   301 	MDataSink& aDataSink )
       
   302     {
       
   303 #ifdef _DEBUG
       
   304 	RDebug::Print(_L("CAdvancedAudioRecordController::RemoveDataSourceL"));
       
   305 #endif
       
   306     if ( !iDataSink )
       
   307 		{
       
   308         User::Leave(KErrNotReady);
       
   309 		}
       
   310 
       
   311     if ( iDataSink != &aDataSink )
       
   312 		{
       
   313         User::Leave(KErrArgument);
       
   314 		}
       
   315 
       
   316     if ( iState == ERecording )
       
   317 		{
       
   318         User::Leave(KErrNotReady);
       
   319 		}
       
   320 
       
   321 	iDataSink->SinkThreadLogoff();
       
   322 	iDataSink->SinkStopL();
       
   323     iDataSink = NULL;
       
   324     }
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // CAdvancedAudioRecordController::ResetL
       
   328 // -----------------------------------------------------------------------------
       
   329 //
       
   330 EXPORT_C void CAdvancedAudioRecordController::ResetL()
       
   331     {
       
   332     RemoveDataSourceL(*iDataSource);
       
   333     RemoveDataSinkL(*iDataSink);
       
   334     //ResetSharedBuffersL(iSharedBufferMaxNum, iSharedBufferMaxSize);
       
   335     }
       
   336 
       
   337 // -----------------------------------------------------------------------------
       
   338 // CAdvancedAudioRecordController::PrimeL
       
   339 // -----------------------------------------------------------------------------
       
   340 //
       
   341 EXPORT_C void CAdvancedAudioRecordController::PrimeL()
       
   342     {
       
   343 #ifdef _DEBUG
       
   344 	RDebug::Print(_L("CAdvancedAudioRecordController::PrimeL"));
       
   345 #endif
       
   346     if ( iState == ERecording )
       
   347     	{
       
   348         User::Leave(KErrNotReady);
       
   349 		}
       
   350 
       
   351     CMMFClip* clip = static_cast <CMMFClip*> (iDataSink);
       
   352     clip->SinkPrimeL();
       
   353     clip->SinkThreadLogon(*this);
       
   354 
       
   355 	// Read the default codec configuration parameters from resource file
       
   356 	RArray<TInt>& codecConfigData = CONST_CAST(RArray<TInt>&, iAudioResource->CodecConfigParametersL());
       
   357 	iAudioInput->ConfigureL(iSampleRate, iChannels, iDataType, codecConfigData);
       
   358     iAudioInput->PrimeL();
       
   359     }
       
   360 
       
   361 // -----------------------------------------------------------------------------
       
   362 // CAdvancedAudioRecordController::Play
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 EXPORT_C void CAdvancedAudioRecordController::PlayL()
       
   366     {
       
   367 #ifdef _DEBUG
       
   368 	RDebug::Print(_L("CAdvancedAudioRecordController::PlayL"));
       
   369 #endif
       
   370     ResetSharedBuffersL(iSharedBufferMaxNum, iSharedBufferMaxSize);
       
   371     for (TInt i = 0; i < iSharedBufferMaxNum; i++)
       
   372         {
       
   373         iSharedBuffers[i]->SetStatus(EAvailable);
       
   374         }
       
   375     iOutstandingPos = 0;
       
   376     iAudioInput->RecordL(&iSharedBuffers);
       
   377     iState = ERecording;
       
   378     }
       
   379 
       
   380 // -----------------------------------------------------------------------------
       
   381 // CAdvancedAudioRecordController::StopL
       
   382 // -----------------------------------------------------------------------------
       
   383 //
       
   384 EXPORT_C void CAdvancedAudioRecordController::StopL()
       
   385     {
       
   386 #ifdef _DEBUG
       
   387 	RDebug::Print(_L("CAdvancedAudioRecordController::StopL [state=%d]"), iState);
       
   388 #endif
       
   389     switch ( iState )
       
   390         {
       
   391         case ERecording:
       
   392             iState = EStopping;
       
   393             DoStopL();
       
   394             SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, KErrNone));
       
   395             break;
       
   396 
       
   397         case EWritingStopped:
       
   398             DoStopL();
       
   399             break;
       
   400 
       
   401         case EStopped:
       
   402         case EStopping:
       
   403             break;
       
   404 
       
   405         default:
       
   406 #ifdef _DEBUG
       
   407 	RDebug::Print(_L("CAdvancedAudioRecordController::StopL Panic iState [%d]"), iState);
       
   408 #endif
       
   409             Panic(KErrGeneral);
       
   410             break;
       
   411         }
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CAdvancedAudioRecordController::PositionL
       
   416 // -----------------------------------------------------------------------------
       
   417 //
       
   418 EXPORT_C TTimeIntervalMicroSeconds CAdvancedAudioRecordController::PositionL() const
       
   419     {
       
   420 #ifdef _DEBUG
       
   421 	RDebug::Print(_L("CAdvancedAudioRecordController::PositionL"));
       
   422 #endif
       
   423     if ( iState == ERecording )
       
   424         {
       
   425         return TTimeIntervalMicroSeconds(iTimePositionInMicroSecs + iAudioInput->CalculateAudioInputPositionL());
       
   426         }
       
   427     else
       
   428         {
       
   429         return TTimeIntervalMicroSeconds(iTimePositionInMicroSecs);
       
   430         }
       
   431     }
       
   432 
       
   433 // -----------------------------------------------------------------------------
       
   434 // CAdvancedAudioRecordController::SetPositionL
       
   435 // -----------------------------------------------------------------------------
       
   436 //
       
   437 EXPORT_C void CAdvancedAudioRecordController::SetPositionL(
       
   438 	const TTimeIntervalMicroSeconds& aPosition )
       
   439     {
       
   440 #ifdef _DEBUG
       
   441 	RDebug::Print(_L("CAdvancedAudioRecordController::SetPositionL(%d)"), I64INT(aPosition.Int64()));
       
   442 #endif
       
   443     if ( aPosition.Int64() == iDuration )
       
   444         {// We hit the end boundary
       
   445         iTimePositionInMicroSecs = aPosition.Int64();
       
   446         iSinkWritePosition = static_cast <CMMFClip*> (iDataSink)->Size();
       
   447         }
       
   448     else if ( aPosition.Int64() == 0 )
       
   449         {
       
   450         iTimePositionInMicroSecs = 0;
       
   451         iSinkWritePosition = 0;
       
   452         }
       
   453     else // Non-boundary request
       
   454         {
       
   455         TInt framePos = iAudioUtility->FindFramePos(aPosition.Int64());
       
   456         if ( framePos != KErrNotFound )
       
   457             {
       
   458             iTimePositionInMicroSecs = aPosition.Int64();
       
   459             iSinkWritePosition = framePos + iAudioUtility->HeaderOffset();
       
   460             }
       
   461         else
       
   462             {
       
   463             User::Leave(KErrArgument);
       
   464             }
       
   465         }
       
   466     }
       
   467 
       
   468 // -----------------------------------------------------------------------------
       
   469 // CAdvancedAudioRecordController::MacGetSourceSampleRateL
       
   470 // Returns the sampling rate obtrained from the audio input.
       
   471 // -----------------------------------------------------------------------------
       
   472 //
       
   473 EXPORT_C void CAdvancedAudioRecordController::MacGetSourceSampleRateL(
       
   474 	TUint& aRate )
       
   475     {
       
   476     if ( !iDataSource )
       
   477     	{
       
   478         User::Leave(KErrNotReady);
       
   479 		}
       
   480 
       
   481     RArray<TUint> rates;
       
   482     CleanupClosePushL(rates);
       
   483     iAudioInput->ConfigRatesL(rates);
       
   484 
       
   485     ASSERT(rates.Count() == 1);
       
   486     aRate = rates[0];
       
   487     CleanupStack::PopAndDestroy(&rates);	// rates
       
   488     }
       
   489 
       
   490 // -----------------------------------------------------------------------------
       
   491 // CAdvancedAudioRecordController::MacGetSourceBitRateL
       
   492 // Default implementation.
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 EXPORT_C void CAdvancedAudioRecordController::MacGetSourceBitRateL(
       
   496 	TUint& /*aRate*/ )
       
   497     {
       
   498     User::Leave(KErrNotSupported);
       
   499     }
       
   500 
       
   501 // -----------------------------------------------------------------------------
       
   502 // CAdvancedAudioRecordController::MacGetSourceNumChannelsL
       
   503 // Returns the number of channels obtrained from the audio input.
       
   504 // -----------------------------------------------------------------------------
       
   505 //
       
   506 EXPORT_C void CAdvancedAudioRecordController::MacGetSourceNumChannelsL(
       
   507 	TUint& aNumChannels )
       
   508     {
       
   509     if ( !iDataSource )
       
   510     	{
       
   511         User::Leave(KErrNotReady);
       
   512 		}
       
   513 
       
   514     RArray<TUint> channels;
       
   515     CleanupClosePushL(channels);
       
   516     iAudioInput->ConfigChannelsL(channels);
       
   517 
       
   518     ASSERT(channels.Count() == 1);
       
   519     aNumChannels = channels[0];
       
   520     CleanupStack::PopAndDestroy(&channels);	// channels
       
   521     }
       
   522 
       
   523 // -----------------------------------------------------------------------------
       
   524 // CAdvancedAudioRecordController::MacGetSourceDataTypeL
       
   525 // Returns the data type obtrained from the audio input.
       
   526 // -----------------------------------------------------------------------------
       
   527 //
       
   528 EXPORT_C void CAdvancedAudioRecordController::MacGetSourceDataTypeL(
       
   529 	TFourCC& aDataType )
       
   530     {
       
   531     if ( !iDataSource )
       
   532     	{
       
   533         User::Leave(KErrNotReady);
       
   534 		}
       
   535 
       
   536     RArray<TFourCC> dataTypes;
       
   537     CleanupClosePushL(dataTypes);
       
   538     iAudioInput->ConfigDataTypesL(dataTypes);
       
   539 
       
   540     ASSERT(dataTypes.Count() == 1);
       
   541     aDataType = dataTypes[0];
       
   542     CleanupStack::PopAndDestroy(&dataTypes);	// dataTypes
       
   543     }
       
   544 
       
   545 // -----------------------------------------------------------------------------
       
   546 // CAdvancedAudioRecordController::MacGetSinkSampleRateL
       
   547 // -----------------------------------------------------------------------------
       
   548 //
       
   549 EXPORT_C void CAdvancedAudioRecordController::MacGetSinkSampleRateL(
       
   550 	TUint& aRate )
       
   551     {
       
   552     if ( !iDataSink )
       
   553     	{
       
   554         User::Leave(KErrNotReady);
       
   555     	}
       
   556     aRate = iSampleRate;
       
   557     }
       
   558 
       
   559 // -----------------------------------------------------------------------------
       
   560 // CAdvancedAudioRecordController::MacGetSinkBitRateL
       
   561 // -----------------------------------------------------------------------------
       
   562 //
       
   563 EXPORT_C void CAdvancedAudioRecordController::MacGetSinkBitRateL(
       
   564 	TUint& aRate )
       
   565     {
       
   566     if ( !iDataSink )
       
   567     	{
       
   568         User::Leave(KErrNotReady);
       
   569     	}
       
   570     aRate = iBitRate;
       
   571     }
       
   572 
       
   573 // -----------------------------------------------------------------------------
       
   574 // CAdvancedAudioRecordController::MacGetSinkNumChannelsL
       
   575 // -----------------------------------------------------------------------------
       
   576 //
       
   577 EXPORT_C void CAdvancedAudioRecordController::MacGetSinkNumChannelsL(
       
   578 	TUint& aNumChannels )
       
   579     {
       
   580     if ( !iDataSink )
       
   581     	{
       
   582         User::Leave(KErrNotReady);
       
   583     	}
       
   584     aNumChannels = iChannels;
       
   585     }
       
   586 
       
   587 // -----------------------------------------------------------------------------
       
   588 // CAdvancedAudioRecordController::MacGetSinkDataTypeL
       
   589 // -----------------------------------------------------------------------------
       
   590 //
       
   591 EXPORT_C void CAdvancedAudioRecordController::MacGetSinkDataTypeL(
       
   592 	TFourCC& aDataType )
       
   593     {
       
   594     if ( !iDataSink )
       
   595     	{
       
   596         User::Leave(KErrNotReady);
       
   597 		}
       
   598     aDataType = iDataType;
       
   599     }
       
   600 
       
   601 // -----------------------------------------------------------------------------
       
   602 // CAdvancedAudioRecordController::MacGetSupportedSourceSampleRatesL
       
   603 // -----------------------------------------------------------------------------
       
   604 //
       
   605 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSourceSampleRatesL(
       
   606 	RArray<TUint>& aSupportedRates )
       
   607     {
       
   608     if ( !iDataSource )
       
   609     	{
       
   610         User::Leave(KErrNotReady);
       
   611 		}
       
   612     aSupportedRates.Reset();
       
   613     iAudioInput->CapabilitiesRatesL(aSupportedRates);
       
   614 	}
       
   615 
       
   616 // -----------------------------------------------------------------------------
       
   617 // CAdvancedAudioRecordController::MacGetSupportedSourceBitRatesL
       
   618 // Default implementation.
       
   619 // -----------------------------------------------------------------------------
       
   620 //
       
   621 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSourceBitRatesL(
       
   622 	RArray<TUint>& /*aSupportedRates*/ )
       
   623     {
       
   624     User::Leave(KErrNotSupported);
       
   625     }
       
   626 
       
   627 // -----------------------------------------------------------------------------
       
   628 // CAdvancedAudioRecordController::MacGetSupportedSourceNumChannelsL
       
   629 // -----------------------------------------------------------------------------
       
   630 //
       
   631 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSourceNumChannelsL(
       
   632 	RArray<TUint>& aSupportedChannels )
       
   633     {
       
   634     if ( !iDataSource )
       
   635     	{
       
   636         User::Leave(KErrNotReady);
       
   637 		}
       
   638     aSupportedChannels.Reset();
       
   639     iAudioInput->CapabilitiesChannelsL(aSupportedChannels);
       
   640 	}
       
   641 
       
   642 // -----------------------------------------------------------------------------
       
   643 // CAdvancedAudioRecordController::MacGetSupportedSourceDataTypesL
       
   644 // -----------------------------------------------------------------------------
       
   645 //
       
   646 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSourceDataTypesL(
       
   647 	RArray<TFourCC>& aSupportedDataTypes )
       
   648     {
       
   649     if ( !iDataSource )
       
   650     	{
       
   651         User::Leave(KErrNotReady);
       
   652 		}
       
   653     aSupportedDataTypes.Reset();
       
   654     iAudioInput->CapabilitiesDataTypesL(aSupportedDataTypes);
       
   655 	}
       
   656 
       
   657 // -----------------------------------------------------------------------------
       
   658 // CAdvancedAudioRecordController::MacGetSupportedSinkSampleRatesL
       
   659 // -----------------------------------------------------------------------------
       
   660 //
       
   661 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSinkSampleRatesL(
       
   662 	RArray<TUint>& aSupportedRates )
       
   663     {
       
   664     if ( !iDataSink )
       
   665     	{
       
   666         User::Leave(KErrNotReady);
       
   667 		}
       
   668     aSupportedRates.Reset();
       
   669     User::LeaveIfError(aSupportedRates.Append(iSampleRate));
       
   670     }
       
   671 
       
   672 // -----------------------------------------------------------------------------
       
   673 // CAdvancedAudioRecordController::MacGetSupportedSinkBitRatesL
       
   674 // -----------------------------------------------------------------------------
       
   675 //
       
   676 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSinkBitRatesL(
       
   677 	RArray<TUint>& aSupportedRates )
       
   678     {
       
   679     if ( !iDataSink )
       
   680     	{
       
   681         User::Leave(KErrNotReady);
       
   682 		}
       
   683     aSupportedRates.Reset();
       
   684     User::LeaveIfError(aSupportedRates.Append(iBitRate));
       
   685     }
       
   686 
       
   687 // -----------------------------------------------------------------------------
       
   688 // CAdvancedAudioRecordController::MacGetSupportedSinkNumChannelsL
       
   689 // -----------------------------------------------------------------------------
       
   690 //
       
   691 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSinkNumChannelsL(
       
   692 	RArray<TUint>& aSupportedChannels )
       
   693     {
       
   694     if ( !iDataSink )
       
   695     	{
       
   696         User::Leave(KErrNotReady);
       
   697 		}
       
   698     aSupportedChannels.Reset();
       
   699     User::LeaveIfError(aSupportedChannels.Append(iChannels));
       
   700     }
       
   701 
       
   702 // -----------------------------------------------------------------------------
       
   703 // CAdvancedAudioRecordController::MacGetSupportedSinkDataTypesL
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 EXPORT_C void CAdvancedAudioRecordController::MacGetSupportedSinkDataTypesL(
       
   707 	RArray<TFourCC>& aSupportedDataTypes )
       
   708     {
       
   709     if ( !iDataSink )
       
   710     	{
       
   711         User::Leave(KErrNotReady);
       
   712 		}
       
   713     aSupportedDataTypes.Reset();
       
   714     User::LeaveIfError(aSupportedDataTypes.Append(iDataType));
       
   715     }
       
   716 
       
   717 // -----------------------------------------------------------------------------
       
   718 // CAdvancedAudioRecordController::MarcGetRecordTimeAvailableL
       
   719 // Default implementation.
       
   720 // -----------------------------------------------------------------------------
       
   721 //
       
   722 EXPORT_C void CAdvancedAudioRecordController::MarcGetRecordTimeAvailableL(
       
   723 	TTimeIntervalMicroSeconds& /*aTime*/ )
       
   724     {
       
   725 	User::Leave(KErrNotSupported);
       
   726     }
       
   727 
       
   728 // -----------------------------------------------------------------------------
       
   729 // CAdvancedAudioRecordController::MarcSetMaxDurationL
       
   730 // Default implementation.
       
   731 // -----------------------------------------------------------------------------
       
   732 //
       
   733 EXPORT_C void CAdvancedAudioRecordController::MarcSetMaxDurationL(
       
   734 	const TTimeIntervalMicroSeconds& /*aMaxDuration*/ )
       
   735     {
       
   736     User::Leave(KErrNotSupported);
       
   737     }
       
   738 
       
   739 // -----------------------------------------------------------------------------
       
   740 // CAdvancedAudioRecordController::MarcSetMaxFileSizeL
       
   741 // -----------------------------------------------------------------------------
       
   742 //
       
   743 EXPORT_C void CAdvancedAudioRecordController::MarcSetMaxFileSizeL(
       
   744 	TInt aFileSize )
       
   745     {
       
   746     iMaxFileSize = aFileSize;
       
   747     }
       
   748 
       
   749 // -----------------------------------------------------------------------------
       
   750 // CAdvancedAudioRecordController::MarcCropL
       
   751 // Default implementation.
       
   752 // -----------------------------------------------------------------------------
       
   753 //
       
   754 EXPORT_C void CAdvancedAudioRecordController::MarcCropL(
       
   755 	TBool aToEnd )
       
   756     {
       
   757     TInt clipSize = static_cast <CMMFClip*> (iDataSink)->Size();
       
   758     TInt64 position = PositionL().Int64();
       
   759     TInt64 duration = DurationL().Int64();
       
   760 
       
   761     if ( !clipSize )
       
   762         {
       
   763         User::Leave(KErrNotFound);
       
   764         }
       
   765 
       
   766     TInt cropPosition = 0;
       
   767 
       
   768     // Convert current position to cropPosition in bytes
       
   769     if ( iSinkWritePosition == clipSize )
       
   770         { // end boundary
       
   771         cropPosition = clipSize;
       
   772         }
       
   773     else if ( iSinkWritePosition == 0 )
       
   774         { // start boundary
       
   775         cropPosition = 0;
       
   776         }
       
   777     else
       
   778         {
       
   779         cropPosition = iAudioUtility->FindFramePos(position) + iAudioUtility->HeaderOffset();
       
   780         }
       
   781 
       
   782     TUint dataSize;  // This will be the size of the data left after cropping.
       
   783 
       
   784     if ( !aToEnd && !cropPosition )
       
   785         {
       
   786         iDataSink->SinkStopL();
       
   787         return;
       
   788         }
       
   789     else if ( !aToEnd ) // crop to start
       
   790         {
       
   791         // Shift the data physically
       
   792         // move the data in blocks
       
   793         // Create a CMMFDataBuffer and use CMMFClip to shift the data
       
   794         dataSize = clipSize - cropPosition;
       
   795         if ( dataSize > 0 )
       
   796             {
       
   797             TUint bufSize = (dataSize < KDefineIOBufferSize ? dataSize : KDefineIOBufferSize); //max bufSize 512
       
   798             CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(bufSize);
       
   799             CleanupStack::PushL(buffer);
       
   800 
       
   801             TInt rPos = cropPosition; // read position
       
   802             TInt wPos = 0;
       
   803             TInt dataToShift = ETrue;
       
   804             while ( dataToShift )
       
   805                 {
       
   806                 static_cast <CMMFClip*>(iDataSink)->ReadBufferL(buffer, rPos);  // synchronous calls
       
   807                 if ( wPos == 0 )
       
   808                     {
       
   809                     WriteHeaderL();
       
   810                     wPos = iAudioUtility->HeaderOffset();
       
   811                     dataSize += wPos;
       
   812                     }
       
   813                 WriteIfEnoughSpaceL(buffer, wPos);
       
   814                 if ( rPos > clipSize )
       
   815                     {
       
   816                     dataToShift = EFalse;  // past the end:  Done
       
   817                     }
       
   818                 else
       
   819                     { // shift the pointers
       
   820                     rPos += bufSize;
       
   821                     wPos += bufSize;
       
   822                     }
       
   823                 }// while data to shift
       
   824             CleanupStack::PopAndDestroy(buffer); // buffer
       
   825             }// if data to shift
       
   826         }
       
   827     else // crop to end
       
   828         {
       
   829         dataSize = cropPosition;
       
   830         }
       
   831 
       
   832     // Physical chop
       
   833     static_cast <CMMFFile*> (iDataSink)->FileL().SetSize(dataSize);
       
   834 
       
   835     delete iAudioUtility;
       
   836     iAudioUtility = NULL; // Get rid of old position array
       
   837     DoAddDataSinkL();	// AK - Used to be InitSinkDataL(EFalse);
       
   838 
       
   839     if ( !aToEnd )
       
   840         {
       
   841         iSinkWritePosition = static_cast <CMMFClip*> (iDataSink)->Size();
       
   842         iTimePositionInMicroSecs = duration - position;
       
   843         }
       
   844     }
       
   845 
       
   846 // -----------------------------------------------------------------------------
       
   847 // CAdvancedAudioRecordController::MarcAddMetaDataEntryL
       
   848 // Default implementation.
       
   849 // -----------------------------------------------------------------------------
       
   850 //
       
   851 EXPORT_C void CAdvancedAudioRecordController::MarcAddMetaDataEntryL(
       
   852 	const CMMFMetaDataEntry& /*aNewEntry*/ )
       
   853     {
       
   854     User::Leave(KErrNotSupported);
       
   855     }
       
   856 
       
   857 // -----------------------------------------------------------------------------
       
   858 // CAdvancedAudioRecordController::MarcRemoveMetaDataEntryL
       
   859 // Default implementation.
       
   860 // -----------------------------------------------------------------------------
       
   861 //
       
   862 EXPORT_C void CAdvancedAudioRecordController::MarcRemoveMetaDataEntryL(
       
   863 	TInt /*aIndex*/ )
       
   864     {
       
   865     User::Leave(KErrNotSupported);
       
   866     }
       
   867 
       
   868 // -----------------------------------------------------------------------------
       
   869 // CAdvancedAudioRecordController::MarcReplaceMetaDataEntryL
       
   870 // Default implementation.
       
   871 // -----------------------------------------------------------------------------
       
   872 //
       
   873 EXPORT_C void CAdvancedAudioRecordController::MarcReplaceMetaDataEntryL(
       
   874 	TInt /*aIndex*/,
       
   875 	const CMMFMetaDataEntry& /*aNewEntry*/ )
       
   876     {
       
   877     User::Leave(KErrNotSupported);
       
   878     }
       
   879 
       
   880 // -----------------------------------------------------------------------------
       
   881 // CAdvancedAudioRecordController::MardSetGainL
       
   882 // -----------------------------------------------------------------------------
       
   883 //
       
   884 EXPORT_C void CAdvancedAudioRecordController::MardSetGainL(
       
   885 	TInt aGain )
       
   886     {
       
   887     if ( !iDataSource )
       
   888     	{
       
   889         User::Leave(KErrNotReady);
       
   890 		}
       
   891 
       
   892     if( aGain > iAudioInput->MaxGainL() )
       
   893     	{
       
   894         User::Leave(KErrArgument);
       
   895 		}
       
   896 
       
   897     iAudioInput->SetGainL(aGain);
       
   898     }
       
   899 
       
   900 // -----------------------------------------------------------------------------
       
   901 // CAdvancedAudioRecordController::MardGetMaxGainL
       
   902 // -----------------------------------------------------------------------------
       
   903 //
       
   904 EXPORT_C void CAdvancedAudioRecordController::MardGetMaxGainL(
       
   905 	TInt& aMaxGain )
       
   906     {
       
   907     if ( !iDataSource )
       
   908     	{
       
   909         User::Leave(KErrNotReady);
       
   910 		}
       
   911 
       
   912     aMaxGain = iAudioInput->MaxGainL();
       
   913     }
       
   914 
       
   915 // -----------------------------------------------------------------------------
       
   916 // CAdvancedAudioRecordController::MardGetGainL
       
   917 // -----------------------------------------------------------------------------
       
   918 //
       
   919 EXPORT_C void CAdvancedAudioRecordController::MardGetGainL(
       
   920 	TInt& aGain )
       
   921     {
       
   922     if ( !iDataSource )
       
   923     	{
       
   924         User::Leave(KErrNotReady);
       
   925 		}
       
   926 
       
   927     aGain = iAudioInput->GainL();
       
   928     }
       
   929 
       
   930 // -----------------------------------------------------------------------------
       
   931 // CAdvancedAudioRecordController::MardSetBalanceL
       
   932 // -----------------------------------------------------------------------------
       
   933 //
       
   934 EXPORT_C void CAdvancedAudioRecordController::MardSetBalanceL(
       
   935 	TInt /*aBalance*/ )
       
   936     {
       
   937     User::Leave(KErrNotSupported);
       
   938     }
       
   939 
       
   940 // -----------------------------------------------------------------------------
       
   941 // CAdvancedAudioRecordController::MardGetBalanceL
       
   942 // Default implementation.
       
   943 // -----------------------------------------------------------------------------
       
   944 //
       
   945 EXPORT_C void CAdvancedAudioRecordController::MardGetBalanceL(
       
   946 	TInt& /*aBalance*/ )
       
   947     {
       
   948     User::Leave(KErrNotSupported);
       
   949     }
       
   950 
       
   951 // -----------------------------------------------------------------------------
       
   952 // CAdvancedAudioRecordController::BufferEmptiedL
       
   953 // -----------------------------------------------------------------------------
       
   954 //
       
   955 EXPORT_C void CAdvancedAudioRecordController::BufferEmptiedL(
       
   956 	CMMFBuffer* aBuffer )
       
   957     {
       
   958     iSinkWritePosition += aBuffer->BufferSize();
       
   959 
       
   960     if (aBuffer->Status() == EBeingEmptied)    // Async request callback
       
   961         iOutstandingPos -= aBuffer->BufferSize();
       
   962 #ifdef _DEBUG
       
   963     RDebug::Print(_L("CAdvancedAudioRecordController::BufferEmptiedL iSinkWritePosition [%d]"), iSinkWritePosition);
       
   964 #endif
       
   965 
       
   966     iAudioUtility->ScanFramesL(static_cast <CMMFClip*> (iDataSink), static_cast <CMMFDataBuffer*> (aBuffer), ETrue);
       
   967     iSampleRate = iAudioUtility->SampleRate();
       
   968     iBitRate = iAudioUtility->BitRate();
       
   969     iChannels = iAudioUtility->Channels();
       
   970     iDuration = iAudioUtility->ScanDuration();
       
   971     aBuffer->SetStatus(EAvailable);
       
   972     }
       
   973 
       
   974 // -----------------------------------------------------------------------------
       
   975 // CAdvancedAudioRecordController::EmptyBufferL
       
   976 // -----------------------------------------------------------------------------
       
   977 //
       
   978 EXPORT_C TInt CAdvancedAudioRecordController::EmptyBufferL(
       
   979 	CMMFBuffer* aBuffer )
       
   980     {
       
   981 #ifdef _DEBUG
       
   982     RDebug::Print(_L("CAdvancedAudioRecordController::EmptyBufferL iSinkWritePosition: %d"), iSinkWritePosition);
       
   983 #endif
       
   984     TInt retVal = KErrNone;
       
   985     TRAP(retVal, DoEmptySharedBufferL(aBuffer));
       
   986     if ( retVal == KErrCompletion )
       
   987         {
       
   988         iState = EWritingStopped;
       
   989         TRAPD(err, DoStopL());
       
   990 		err = err; //to suppress warnings
       
   991         SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, KErrEof));
       
   992         }
       
   993     else if ( retVal )
       
   994         {
       
   995 #ifdef _DEBUG
       
   996     RDebug::Print(_L("Error emptying shared buffer!!! %d"), retVal);
       
   997 #endif
       
   998         iState = EWritingStopped;
       
   999         TRAPD(err, DoStopL());
       
  1000 		err = err;
       
  1001         SendEventToClient(TMMFEvent(KMMFEventCategoryPlaybackComplete, retVal));
       
  1002         }
       
  1003     return retVal;
       
  1004     }
       
  1005 
       
  1006 // -----------------------------------------------------------------------------
       
  1007 // CAdvancedAudioRecordController::RecordComplete
       
  1008 // -----------------------------------------------------------------------------
       
  1009 //
       
  1010 EXPORT_C void CAdvancedAudioRecordController::RecordComplete()
       
  1011     {
       
  1012     iState = EStopped;
       
  1013     }
       
  1014 
       
  1015 // -----------------------------------------------------------------------------
       
  1016 // CAdvancedAudioRecordController::SendEvent
       
  1017 // -----------------------------------------------------------------------------
       
  1018 //
       
  1019 EXPORT_C void CAdvancedAudioRecordController::SendEvent(
       
  1020 	const TMMFEvent& aEvent )
       
  1021     {
       
  1022     SendEventToClient(aEvent);
       
  1023     }
       
  1024 
       
  1025 // -----------------------------------------------------------------------------
       
  1026 // CAdvancedAudioRecordController::DoEmptySharedBufferL
       
  1027 // -----------------------------------------------------------------------------
       
  1028 //
       
  1029 TInt CAdvancedAudioRecordController::DoEmptySharedBufferL(
       
  1030 	CMMFBuffer* aBuffer )
       
  1031     {
       
  1032     switch ( iState )
       
  1033         {
       
  1034         case ERecording:
       
  1035             if ( (iMaxFileSize != -1 && // Max file size is set
       
  1036                  !iSinkWritePosition && // Zero file size
       
  1037                  (aBuffer->BufferSize() + iAudioUtility->HeaderOffset() > static_cast <TUint> (iMaxFileSize)))
       
  1038                  || // OR
       
  1039                  (iMaxFileSize != -1 &&  // Max file size is set
       
  1040                  iSinkWritePosition + aBuffer->BufferSize() > static_cast <TUint> (iMaxFileSize)) )
       
  1041                 {
       
  1042                 WriteIfMaxFileSizeReachedL(aBuffer);
       
  1043                 }
       
  1044             else // Normal case
       
  1045                 {
       
  1046                 WriteIfEnoughSpaceL(aBuffer, iSinkWritePosition, this, aBuffer->BufferSize());
       
  1047                 }
       
  1048             break;
       
  1049 
       
  1050         case EStopping:
       
  1051             if ( (iMaxFileSize != -1 && // Max file size is set
       
  1052                  !iSinkWritePosition && // Zero file size
       
  1053                  (aBuffer->BufferSize() + iAudioUtility->HeaderOffset() > static_cast <TUint> (iMaxFileSize)))
       
  1054                  || // OR
       
  1055                  (iMaxFileSize != -1 && // Max file size is set
       
  1056                  iSinkWritePosition + aBuffer->BufferSize() > static_cast <TUint> (iMaxFileSize)) )
       
  1057                 {
       
  1058                 WriteIfMaxFileSizeReachedL(aBuffer);
       
  1059                 }
       
  1060             else
       
  1061                 {
       
  1062                 // Synchronous write
       
  1063                 WriteIfEnoughSpaceL(aBuffer, iSinkWritePosition, NULL, aBuffer->BufferSize());
       
  1064                 BufferEmptiedL(aBuffer);
       
  1065                 }
       
  1066             break;
       
  1067 
       
  1068         case EWritingStopped:
       
  1069         case EStopped:
       
  1070             break;
       
  1071 
       
  1072         default:
       
  1073             Panic(KErrGeneral);
       
  1074             break;
       
  1075         }
       
  1076     return KErrNone;
       
  1077     }
       
  1078 
       
  1079 // End of file