os/kernelhwsrv/kerneltest/e32test/multimedia/t_sound2.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\multimedia\t_sound2.cpp
    15 //
    16 //
    17 
    18 /**
    19  @file General test code for the shared chunk sound driver - based on T_SOUND.
    20 */
    21 
    22 #include <e32test.h>
    23 #include "t_soundutils.h"
    24 #include <hal.h>
    25 #include <e32def.h>
    26 #include <e32def_private.h>
    27 
    28 // #define SOAKTEST
    29 
    30 const TSoundRate speedTable[] = {ESoundRate48000Hz,ESoundRate44100Hz,ESoundRate32000Hz,ESoundRate29400Hz,
    31 								 ESoundRate24000Hz,ESoundRate22050Hz,ESoundRate16000Hz,ESoundRate14700Hz,
    32 								 ESoundRate12000Hz,ESoundRate11025Hz,ESoundRate9600Hz,ESoundRate8820Hz,
    33 								 ESoundRate8000Hz,ESoundRate7350Hz,(TSoundRate)-1};	// ALL RATES DECENDING
    34 
    35 #define CHECK(aValue) {Test(aValue,__LINE__);}
    36 #define CHECK_NOERROR(aValue) { TInt v=(aValue); if(v) { Test.Printf(_L("Error value = %d\n"),v); Test(EFalse,__LINE__); }}
    37 #define CHECK_EQUAL(aValue1,aValue2) { TInt v1=(aValue1); TInt v2=(aValue2); if(v1!=v2) { Test.Printf(_L("Error value = %d\n"),v1); Test(EFalse,__LINE__); }}
    38 #define CHECK_POSITIVE(aOffset) { if(aOffset<0) { Test.Printf(_L("CHECK_POSITIVE(%d) failed\n"), aOffset); Test(EFalse,__LINE__); } }
    39 
    40 _LIT(KSndLddFileName,"ESOUNDSC.LDD");
    41 _LIT(KSndPddFileName,"SOUNDSC.PDD");
    42 
    43 RTest Test(_L("T_SOUND2"));
    44 RSoundSc TxSoundDevice;
    45 RSoundSc RxSoundDevice;
    46 
    47 TSoundFormatsSupportedV02Buf RecordCapsBuf;
    48 TSoundFormatsSupportedV02Buf PlayCapsBuf;
    49 TCurrentSoundFormatV02Buf PlayFormatBuf;
    50 TCurrentSoundFormatV02Buf RecordFormatBuf;
    51 
    52 LOCAL_C TInt Load()
    53 	{
    54 	TInt r;
    55 
    56 	Test.Start(_L("Load sound PDD"));
    57 	r=User::LoadPhysicalDevice(KSndPddFileName);
    58 	if (r==KErrNotFound)
    59 		{
    60 		Test.End();
    61 		return(r);
    62 		}
    63 	CHECK(r==KErrNone || r==KErrAlreadyExists);
    64 	r=User::LoadPhysicalDevice(KSndPddFileName);
    65 	CHECK(r==KErrAlreadyExists);
    66 
    67 	Test.Next(_L("Load sound LDD"));
    68 	r=User::LoadLogicalDevice(KSndLddFileName);
    69 	CHECK(r==KErrNone || r==KErrAlreadyExists);
    70 	r=User::LoadPhysicalDevice(KSndPddFileName);
    71 	CHECK(r==KErrAlreadyExists);
    72 
    73 	Test.End();
    74 	return(KErrNone);
    75 	}
    76 
    77 LOCAL_C void CheckConfig(const TCurrentSoundFormatV02& aConfig,const TSoundFormatsSupportedV02& aCaps)
    78 	{
    79 	if (!((1<<(aConfig.iChannels-1)) & aCaps.iChannels))
    80 		CHECK_NOERROR(ETrue);
    81 	if (!((1<<aConfig.iRate) & aCaps.iRates))
    82 		CHECK_NOERROR(ETrue);
    83 	if (!((1<<aConfig.iEncoding) & aCaps.iEncodings))
    84 		CHECK_NOERROR(ETrue);
    85 	if (!((1<<aConfig.iDataFormat) & aCaps.iDataFormats))
    86 		CHECK_NOERROR(ETrue);
    87 	}
    88 
    89 
    90 ////////////////////////////////////////////////////////////////////////////////
    91 // Tests
    92 
    93 const TInt KMaxLinearVolume=256;
    94 const TInt KLinearTodB[KMaxLinearVolume+1] =
    95 	{
    96 	0  ,158,170,177,182,186,189,192,194,196,198,200,201,203,204,205,
    97 	206,207,208,209,210,211,212,213,213,214,215,215,216,217,217,218,
    98 	218,219,219,220,220,221,221,222,222,223,223,224,224,224,225,225,
    99 	225,226,226,226,227,227,227,228,228,228,229,229,229,230,230,230,
   100 	230,231,231,231,231,232,232,232,232,233,233,233,233,234,234,234,
   101 	234,235,235,235,235,235,236,236,236,236,236,237,237,237,237,237,
   102 	237,238,238,238,238,238,239,239,239,239,239,239,240,240,240,240,
   103 	240,240,240,241,241,241,241,241,241,241,242,242,242,242,242,242,
   104 	242,243,243,243,243,243,243,243,244,244,244,244,244,244,244,244,
   105 	245,245,245,245,245,245,245,245,245,246,246,246,246,246,246,246,
   106 	246,246,247,247,247,247,247,247,247,247,247,247,248,248,248,248,
   107 	248,248,248,248,248,248,249,249,249,249,249,249,249,249,249,249,
   108 	250,250,250,250,250,250,250,250,250,250,250,250,251,251,251,251,
   109 	251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,252,
   110 	252,252,252,252,252,253,253,253,253,253,253,253,253,253,253,253,
   111 	253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,254,255
   112 	};
   113 
   114 LOCAL_C void TestBasicPlayFunctions()
   115 	{
   116 	TRequestStatus stat[2];
   117 
   118 	Test.Next(_L("Preparing to play..."));
   119 	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   120 		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   121 	PlayFormatBuf().iChannels = 1;
   122 	PrintConfig(PlayFormatBuf(),Test);
   123 	TInt r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
   124 	CHECK_NOERROR(r);
   125 
   126 	// Set the play buffer configuration, then read it back.
   127 	RChunk chunk;
   128 	TInt bufSize=BytesPerSecond(PlayFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
   129 	bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
   130 	TTestSharedChunkBufConfig bufferConfig;
   131 	bufferConfig.iNumBuffers=2;
   132 	bufferConfig.iBufferSizeInBytes=bufSize;
   133 	bufferConfig.iFlags=0;		// All buffers will be contiguous
   134 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   135 	r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   136 	CHECK_NOERROR(r);
   137 	TxSoundDevice.GetBufferConfig(bufferConfigBuf);
   138 	PrintBufferConf(bufferConfig,Test);
   139 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
   140 	TPtr8* tPtr[2];
   141 	TInt i;
   142 	for (i=0;i<2;i++)
   143 		tPtr[i]=new TPtr8(chunk.Base()+bufferConfig.iBufferOffsetList[i],bufSize);
   144 
   145 	/**	@SYMTestCaseID 		PBASE-T_SOUND2-249
   146 	@SYMTestCaseDesc 		Play pause / resume - pausing and resuming before playback has commenced.
   147 	@SYMTestPriority 		Critical
   148 	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer configuration.
   149 							1)	Attempt to resume playback before playback has been started.
   150 							2)	Attempt to pause playback before playback has been started.
   151 	@SYMTestExpectedResults	1)	The resume request should complete with KErrNotReady.
   152 							2)	The pause request should complete with KErrNotReady
   153 	@SYMREQ					PREQ1073.4 */
   154 
   155 	Test.Printf(_L("Resume when not playing\r\n"));
   156 	r=TxSoundDevice.Resume();
   157 	CHECK(r==KErrNotReady)
   158 
   159 	Test.Printf(_L("Pause when not playing\r\n"));
   160 	r=TxSoundDevice.Pause();
   161 	CHECK(r==KErrNotReady)
   162 
   163 	/**	@SYMTestCaseID 		PBASE-T_SOUND2-237
   164 	@SYMTestCaseDesc 		Play operation - with zero length.
   165 	@SYMTestPriority 		Critical
   166 	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer
   167 							configuration. Issue a transfer request from one of the buffers to play data specifying a
   168 							length of zero.
   169 	@SYMTestExpectedResults	The play request should complete with KErrNone.
   170 	@SYMREQ					PREQ1073.4 */
   171 
   172 	Test.Next(_L("Play empty buffer"));
   173 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],0,KSndFlagLastSample);	// Play length of zero
   174 	User::WaitForRequest(stat[0]);
   175 	CHECK_EQUAL(stat[0].Int(),KErrNone);
   176 
   177 	/**	@SYMTestCaseID 		PBASE-T_SOUND2-238
   178 	@SYMTestCaseDesc 		Play operation - with a short transfer.
   179 	@SYMTestPriority 		Critical
   180 	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer configuration.
   181 							1)	Issue a transfer requests from one of the buffers to play data, specifying a length equal to the
   182 								minimum request size that the device supports - i.e.
   183 								TSoundFormatsSupportedV02::iRequestMinSize, or 2 bytes, whichever is greater.
   184 							2)	Issue a transfer requests from one of the buffers to play data, specifying a length equal
   185 								to twice the minimum request size that the device supports, or 34 bytes, whichever
   186 								is greater.
   187 	@SYMTestExpectedResults	1)	The play request should complete with KErrNone.
   188 							2)	The play request should complete with KErrNone.
   189 	@SYMREQ					PREQ1073.4 */
   190 
   191 	Test.Next(_L("Play short buffer"));
   192 	TInt len=Max(2,PlayCapsBuf().iRequestMinSize);
   193 	Test.Printf(_L("Play length is %d bytes\r\n"),len);
   194 	tPtr[0]->FillZ(bufSize);
   195 	tPtr[1]->FillZ(len);
   196 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,0);
   197 	TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],len,KSndFlagLastSample);
   198 	User::WaitForRequest(stat[0]);
   199 	CHECK_EQUAL(stat[0].Int(),KErrNone);
   200 	User::WaitForRequest(stat[1]);
   201 	CHECK_EQUAL(stat[1].Int(),KErrNone);
   202 
   203 	Test.Next(_L("Play a slightly longer buffer"));
   204 	len=Max(34,(PlayCapsBuf().iRequestMinSize<<1));
   205 	if (PlayCapsBuf().iRequestMinSize)
   206 			len&=~(PlayCapsBuf().iRequestMinSize-1);
   207 	Test.Printf(_L("Play length is %d bytes\r\n"),len);
   208 	tPtr[1]->FillZ(bufSize);
   209 	tPtr[0]->FillZ(len);
   210 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[1],bufSize,0); // Play 2nd buffer 1st
   211 	TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[0],len,KSndFlagLastSample);
   212 	User::WaitForRequest(stat[0]);
   213 	CHECK_EQUAL(stat[0].Int(),KErrNone);
   214 	User::WaitForRequest(stat[1]);
   215 	CHECK_EQUAL(stat[1].Int(),KErrNone);
   216 
   217 	/**	@SYMTestCaseID 		PBASE-T_SOUND2-240
   218 	@SYMTestCaseDesc 		Play operation - altering the volume.
   219 	@SYMTestPriority 		Critical
   220 	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer configuration
   221 							so it contains multiple buffers. Using multiple simultaneous play requests, play 4 seconds
   222 							of continuous tone - with each individual play request consisting of 1/8th second of tone.
   223 							Each time a request completes, increase the volume slightly - starting at the minimum
   224 							and ending at maximum volume. (Ensure the last request is marked with the
   225 							KSndFlagLastSample flag).
   226 	@SYMTestExpectedResults	The driver should successfully play 4 seconds of tone with all requests completing with
   227 							KErrNone.
   228 	@SYMREQ					PREQ1073.4 */
   229 
   230 	/**	@SYMTestCaseID 		PBASE-T_SOUND2-250
   231 	@SYMTestCaseDesc 		Play pause / resume - pausing and resuming while playback is in progress.
   232 	@SYMTestPriority 		Critical
   233 	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer configuration
   234 							so it contains multiple buffers. Reset the channel's count of bytes transferred.
   235 							Using multiple simultaneous play requests, play 4 seconds of continuous tone - with
   236 							each individual play request consisting of 1/8th second of tone.
   237 							1)	After 10 requests have completed, pause transfer for 2 seconds, then resume it.
   238 							2)	After 20 requests have completed, attempt to resume playback while playback is not paused.
   239 							3)	With only 0.25 second of tone still to play, pause transfer for 1 second, then resume it.
   240 							4)	10ms after resuming, pause transfer again for 1 second, then resume it.
   241 							5)	Once transfer has completed, read back the count of bytes transferred.
   242 	@SYMTestExpectedResults	1)	Playback of the tone should be interrupted for 2 seconds with the pause and resume requests
   243 								both completing with KErrNone.
   244 							2)	The resume request should complete with KErrNotReady.
   245 							3)	Playback of the tone should be interrupted for 1 second with the pause and resume requests
   246 								both completing with KErrNone.
   247 							4)	Playback of the tone should be interrupted for 1 second with the pause and resume requests
   248 								both completing with KErrNone.
   249 							5)	The count of bytes transferred should not be affected by pausing and resuming playback
   250 								(i.e. it should equal the value calculated for 4 seconds at the selected sampe rate and
   251 								number of channels).
   252 	@SYMREQ					PREQ1073.4 */
   253 
   254 	Test.Next(_L("Playing..."));
   255 	r=MakeSineTable(PlayFormatBuf());
   256 	CHECK_NOERROR(r);
   257 	r=SetToneFrequency(440,PlayFormatBuf());
   258 	CHECK_NOERROR(r);
   259 	TxSoundDevice.ResetBytesTransferred();
   260 	TInt remainingPlayCount = BytesPerSecond(PlayFormatBuf())*4/bufSize;
   261 
   262 	// Set the initial value for the volume.
   263 	TInt bytesToPlay = remainingPlayCount*bufSize;
   264 	TInt bytesPlayed = 0;
   265 	TInt vol = I64LOW(TInt64(KMaxLinearVolume)*TInt64(bytesPlayed)/TInt64(bytesToPlay));
   266 	vol = KLinearTodB[vol];			// Rather than varying the volume logarithmically (in dB), vary it linearly (as done by MM).
   267 	TxSoundDevice.SetVolume(vol);
   268 
   269 	// Issue a pair of play requests.
   270 	WriteTone(*tPtr[0],PlayFormatBuf());
   271 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize);
   272 	WriteTone(*tPtr[1],PlayFormatBuf());
   273 	TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],bufSize);
   274 
   275 	TInt lcount = 0;
   276 	TUint flags;
   277 	while (remainingPlayCount>2)
   278 		{
   279 		// Wait for either of the outstanding play requests to complete.
   280 		User::WaitForAnyRequest();
   281 		remainingPlayCount--;
   282 
   283 		// Work out which request this applies to.
   284 		for (i=0;i<2;i++)
   285 			{
   286 			if (stat[i]!=KRequestPending)
   287 				break;
   288 			}
   289 		CHECK(i<2);
   290 		CHECK_NOERROR(stat[i].Int());
   291 
   292 		// Issue a further play request using the buffer just made free.
   293 		WriteTone(*tPtr[i],PlayFormatBuf());
   294 		flags=(remainingPlayCount<=2)?KSndFlagLastSample:0;
   295 		TxSoundDevice.PlayData(stat[i],bufferConfig.iBufferOffsetList[i],bufSize,flags);
   296 
   297 		// Adjust the volume
   298 		bytesPlayed = TxSoundDevice.BytesTransferred();
   299 		vol = I64LOW(TInt64(KMaxLinearVolume)*TInt64(bytesPlayed)/TInt64(bytesToPlay));
   300 		vol = KLinearTodB[vol];			// Rather than varying the volume logarithmically (in dB), vary it linearly (as done by MM).
   301 		Test.Printf(_L("Bytes played = %d (vol = %d)\r\n"),bytesPlayed,vol);
   302 		TxSoundDevice.SetVolume(vol);
   303 
   304 		if (lcount == 10)
   305 			{
   306 			// Do a pause/resume
   307 			r=TxSoundDevice.Pause();
   308 			CHECK_NOERROR(r);
   309 			Test.Printf(_L("Pause 2 seconds\r\n"));
   310 			User::After(2000000);
   311 			Test.Printf(_L("Restart\r\n"));
   312 			r=TxSoundDevice.Resume();
   313 			CHECK_NOERROR(r);
   314 			}
   315 		if (lcount == 20)
   316 			{
   317 			Test.Printf(_L("Resume when playing\r\n"));
   318 			r=TxSoundDevice.Resume();
   319 			CHECK(r==KErrNotReady)
   320 			}
   321 
   322 		CHECK_EQUAL(TxSoundDevice.Volume(),vol);
   323 		CHECK_EQUAL(TxSoundDevice.SetAudioFormat(PlayFormatBuf),KErrInUse);
   324 		lcount++;
   325 		}
   326 
   327 	// Last 2 play requests still outstanding - do a pause/resume
   328 	r=TxSoundDevice.Pause();
   329 	CHECK_NOERROR(r);
   330 	Test.Printf(_L("Pause 1 second\r\n"));
   331 	User::After(1000000);
   332 	Test.Printf(_L("Restart\r\n"));
   333 	r=TxSoundDevice.Resume();
   334 	CHECK_NOERROR(r);
   335 	bytesPlayed = TxSoundDevice.BytesTransferred();
   336 
   337 	User::After(10000); // 10ms
   338 
   339 	r=TxSoundDevice.Pause();
   340 	Test.Printf(_L("Bytes played = %d\r\n"),bytesPlayed);
   341 
   342 	CHECK_NOERROR(r);
   343 	Test.Printf(_L("Pause 1 second\r\n"));
   344 	User::After(1000000);
   345 	Test.Printf(_L("Restart\r\n"));
   346 	r=TxSoundDevice.Resume();
   347 	CHECK_NOERROR(r);
   348 	bytesPlayed = TxSoundDevice.BytesTransferred();
   349 	Test.Printf(_L("Bytes played = %d\r\n"),bytesPlayed);
   350 
   351 	User::WaitForRequest(stat[0]);
   352 	CHECK_EQUAL(stat[0].Int(),KErrNone);
   353 	User::WaitForRequest(stat[1]);
   354 	CHECK_EQUAL(stat[1].Int(),KErrNone);
   355 
   356 	bytesPlayed = TxSoundDevice.BytesTransferred();
   357 	Test.Printf(_L("Bytes played = %d vs %d\n"),bytesPlayed, bytesToPlay);
   358 	CHECK_EQUAL(bytesToPlay,bytesPlayed);
   359 
   360 	TxSoundDevice.ResetBytesTransferred();
   361 	CHECK_EQUAL(TxSoundDevice.BytesTransferred(),0);
   362 
   363 	Test.Next(_L("Pause and resume when not playing"));
   364 	TxSoundDevice.Pause();
   365 	TxSoundDevice.Resume();
   366 
   367 	chunk.Close();
   368 	for (i=0;i<2;i++)
   369 		delete tPtr[i];
   370 	}
   371 
   372 LOCAL_C void TestBasicRecordFunctions()
   373 	{
   374 	TRequestStatus stat;
   375 	TInt length, r, i;
   376 
   377 	Test.Next(_L("Preparing to record..."));
   378 
   379 	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   380 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   381 	RecordFormatBuf().iChannels = 2;
   382 
   383 	// find first supported rate and set the the audio configuration to use it
   384 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
   385 		{
   386 		RecordFormatBuf().iRate = (TSoundRate)i;
   387 		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
   388 		if (RecordCapsBuf().iRates & (1<<i))
   389 			{
   390 			CHECK_NOERROR(r);				// Caps reports it is supported
   391 			break;
   392 			}
   393 		}
   394 
   395 	PrintConfig(RecordFormatBuf(),Test);
   396 
   397 	// Set the record buffer configuration, then read it back.
   398 	RChunk chunk;
   399 	TInt bufSize=BytesPerSecond(RecordFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
   400 	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());	// Keep the buffer length valid for driver.
   401 	TTestSharedChunkBufConfig bufferConfig;
   402 	bufferConfig.iNumBuffers=3;
   403 	bufferConfig.iBufferSizeInBytes=bufSize;
   404 	bufferConfig.iFlags=0;																// All buffers will be contiguous
   405 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   406 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   407 	CHECK_NOERROR(r);
   408 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
   409 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
   410 
   411 	Test.Next(_L("Test for record overflow"));
   412 	RxSoundDevice.SetVolume(KSoundMaxVolume);
   413 	RxSoundDevice.RecordData(stat,length);
   414 	User::WaitForRequest(stat);
   415 	TInt retOffset=stat.Int();
   416 	CHECK_POSITIVE(retOffset);
   417 	CHECK(length>0);
   418 	r=RxSoundDevice.ReleaseBuffer(retOffset);
   419 	CHECK_NOERROR(r);
   420 
   421 	User::After(500000);			// Wait 1/2 second for data overflow.
   422 
   423 	RxSoundDevice.RecordData(stat,length);
   424 	User::WaitForRequest(stat);
   425 	retOffset=stat.Int();
   426 	CHECK(retOffset==KErrOverflow);
   427 
   428 	// Make sure we can issue a successful RecordData after recovering from overflow.
   429 	RxSoundDevice.RecordData(stat,length);
   430 	User::WaitForRequest(stat);
   431 	retOffset=stat.Int();
   432 	CHECK_POSITIVE(retOffset);
   433     r=RxSoundDevice.ReleaseBuffer(retOffset);
   434     CHECK_NOERROR(r);
   435 
   436 	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
   437 	chunk.Close();
   438 	}
   439 
   440 /**	@SYMTestCaseID 			PBASE-T_SOUND2-241
   441 	@SYMTestCaseDesc 		Play operation - playing all rates.
   442 	@SYMTestPriority 		Critical
   443 	@SYMTestActions			1)	For each of the sample rates supported by the device, setup the audio configuration
   444 								on the playback channel for mono operation (i.e. 1 audio channel) and then setup
   445 								the buffer configuration so it contains multiple buffers. Using multiple simultaneous play requests,
   446 								play 4 seconds of continuous tone - with each individual play request consisting of 1/8th second of
   447 								tone. (Ensure the last request is marked with the KSndFlagLastSample flag).
   448 							2)	Repeat the above with the driver configured for stereo operation (i.e. 2 audio channels).
   449 	@SYMTestExpectedResults	1)	For each of the sample rates supported by the device, the driver should successfully play
   450 								4 seconds of tone, with no interruptions in the sound produced and with all requests
   451 								completing with KErrNone.
   452 							2)	For each of the sample rates supported by the device, the driver should successfully play
   453 								4 seconds of tone, with no interruptions in the sound produced and with all requests
   454 								completing with KErrNone.
   455 	@SYMREQ					PREQ1073.4
   456 */
   457 LOCAL_C void TestPlayAllRates(TInt aNumChannels,TInt aNumSeconds)
   458 	{
   459 	TRequestStatus stat[2];
   460 	TPtr8* tPtr[2];
   461 	TInt i;
   462 	for (i=0;i<2;i++)
   463 		tPtr[i]=new TPtr8(NULL,0);
   464 
   465 	Test.Next(_L("Play all rates test"));
   466 	Test.Printf(_L("Number of channels %d, duration %d seconds\n"), aNumChannels, aNumSeconds);
   467 
   468 	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   469 		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   470 	PlayFormatBuf().iChannels = aNumChannels;
   471 	TInt r=MakeSineTable(PlayFormatBuf());
   472 	CHECK_NOERROR(r);
   473 
   474 	TxSoundDevice.SetVolume(KSoundMaxVolume);
   475 
   476 	RChunk chunk;
   477 	TInt speed = 0;
   478 	while (speedTable[speed]>=0)
   479 		{
   480 		PlayFormatBuf().iRate = speedTable[speed++];
   481 		PlayFormatBuf().iChannels = aNumChannels;
   482 
   483 		// Set the play format.
   484 		Test.Printf(_L("Testing playback rate %d...\r\n"),RateInSamplesPerSecond(PlayFormatBuf().iRate));
   485 		r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
   486 		if (r==KErrNotSupported)
   487 			{
   488 			Test.Printf(_L("Sample rate not supported\r\n"));
   489 			continue;
   490 			}
   491 		CHECK_NOERROR(r);
   492 
   493 		// Set the play buffer configuration, then read it back.
   494 		TInt bufSize=BytesPerSecond(PlayFormatBuf())/4; 	 								// Large enough to hold 1/4th second of data.
   495 		bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
   496 		TTestSharedChunkBufConfig bufferConfig;
   497 		bufferConfig.iNumBuffers=2;
   498 		bufferConfig.iBufferSizeInBytes=bufSize;
   499 		bufferConfig.iFlags=0;																// All buffers will be contiguous
   500 		TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   501 		r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   502 		CHECK_NOERROR(r);
   503 		TxSoundDevice.GetBufferConfig(bufferConfigBuf);
   504 		PrintBufferConf(bufferConfig,Test);
   505 		CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
   506 		tPtr[0]->Set(chunk.Base()+bufferConfig.iBufferOffsetList[0],0,bufSize);
   507 		tPtr[1]->Set(chunk.Base()+bufferConfig.iBufferOffsetList[1],0,bufSize);
   508 
   509 		r=SetToneFrequency(440,PlayFormatBuf());
   510 		CHECK_NOERROR(r);
   511 		TxSoundDevice.ResetBytesTransferred();
   512 		CHECK_EQUAL(TxSoundDevice.BytesTransferred(),0);
   513 
   514 		// Issue a pair of play requests.
   515 		WriteTone(*tPtr[0],PlayFormatBuf());
   516 		TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize);
   517 		WriteTone(*tPtr[1],PlayFormatBuf());
   518 		TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],bufSize);
   519 
   520 		TInt remainingPlayCount = BytesPerSecond(PlayFormatBuf())*aNumSeconds/bufSize;
   521 		TInt bytesToPlay = remainingPlayCount*bufSize;
   522 		TInt bytesPlayed = 0;
   523 		TInt i;
   524 		TUint flags;
   525 		while(remainingPlayCount>2)
   526 			{
   527 			// Wait for either of the outstanding play requests to complete.
   528 			User::WaitForAnyRequest();
   529 			remainingPlayCount--;
   530 
   531 			// Work out which request this applies to.
   532 			for (i=0;i<2;i++)
   533 				{
   534 				if (stat[i]!=KRequestPending)
   535 					break;
   536 				}
   537 			CHECK(i<2);
   538 			CHECK_NOERROR(stat[i].Int());
   539 
   540 			WriteTone(*tPtr[i],PlayFormatBuf());
   541 			flags=(remainingPlayCount<=2)?KSndFlagLastSample:0;
   542 			TxSoundDevice.PlayData(stat[i],bufferConfig.iBufferOffsetList[i],bufSize,flags);
   543 			}
   544 
   545 		// Last 2 play requests still outstanding.
   546 		User::WaitForRequest(stat[0]);
   547 		CHECK_NOERROR(stat[0].Int());
   548 		User::WaitForRequest(stat[1]);
   549 		CHECK_NOERROR(stat[1].Int());
   550 
   551 		Test.Printf(_L("Sample rate successful\r\n"));
   552 		bytesPlayed = TxSoundDevice.BytesTransferred();
   553 		CHECK_EQUAL(bytesToPlay,bytesPlayed);
   554 		chunk.Close();
   555 		}
   556 
   557 	for (i=0;i<2;i++)
   558 		delete tPtr[i];
   559 	}
   560 
   561 /**	@SYMTestCaseID 			PBASE-T_SOUND2-254
   562 	@SYMTestCaseDesc 		Record operation - recording all rates.
   563 	@SYMTestPriority 		Critical
   564 	@SYMTestActions			1)	For each of the sample rates supported by the device, setup the audio configuration on
   565 								the record channel for mono operation (i.e. 1 audio channel) and then setup the buffer
   566 								configuration so it contains multiple buffers. Using multiple simultaneous record
   567 								requests, record 4 seconds of audio data - with each individual record request being
   568 								for 1/8th second of data.
   569 							2)	Repeat the above with the driver configured for stereo operation (i.e. 2 audio channels).
   570 	@SYMTestExpectedResults	1)	For each of the sample rates supported by the device, the driver should successfully
   571 							record 4 seconds of data, with all requests completing with KErrNone.
   572 							2)	For each of the sample rates supported by the device, the driver should successfully
   573 							record 4 seconds of data, with all requests completing with KErrNone
   574 	@SYMREQ					PREQ1073.4
   575 */
   576 LOCAL_C void TestRecordAllRates(TInt aNumChannels,TInt aNumSeconds)
   577 	{
   578 
   579 	TRequestStatus stat[2];
   580 	TInt length[2];
   581 
   582 	Test.Next(_L("Record all rate test"));
   583 	Test.Printf(_L("Number of channels %d, duration %d seconds\n"), aNumChannels, aNumSeconds);
   584 
   585 	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   586 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   587 
   588 	RChunk chunk;
   589 	TInt speed = 0;
   590 	while (speedTable[speed]>=0)
   591 		{
   592 		RecordFormatBuf().iRate = speedTable[speed++];
   593 		RecordFormatBuf().iChannels = aNumChannels;
   594 
   595 		// Set the record format.
   596 		Test.Printf(_L("Testing record rate %d...\r\n"),RateInSamplesPerSecond(RecordFormatBuf().iRate));
   597 		TInt r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
   598 		if (r==KErrNotSupported)
   599 			{
   600 			Test.Printf(_L("Sample rate not supported\r\n"));
   601 			continue;
   602 			}
   603 		CHECK_NOERROR(r);
   604 
   605 		// Set the record buffer configuration, then read it back.
   606 		TInt bufSize=BytesPerSecond(RecordFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
   607 		bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());	// Keep the buffer length valid for driver.
   608 		TTestSharedChunkBufConfig bufferConfig;
   609 		bufferConfig.iNumBuffers=4;
   610 		bufferConfig.iBufferSizeInBytes=bufSize;
   611 		bufferConfig.iFlags=0;																// All buffers will be contiguous
   612 		TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   613 		r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   614 		CHECK_NOERROR(r);
   615 		RxSoundDevice.GetBufferConfig(bufferConfigBuf);
   616 		PrintBufferConf(bufferConfig,Test);
   617 		CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
   618 
   619 		TInt remainingRecordCount = BytesPerSecond(RecordFormatBuf())*aNumSeconds/bufSize;
   620 		TInt bytesToRecord = remainingRecordCount*bufSize;
   621 		TInt bytesRecorded = 0;
   622 
   623 		// The driver rounds up the buffer size to the nearest page meaning the total duration
   624 		// to complete this test won't be exactly equal to 'aNumSeconds' anymore. Hence, the
   625 		// predicted time is no longer simply: aNumSeconds * 1000000.
   626 		TInt64 predictedTime = (bufSize * remainingRecordCount);
   627 		predictedTime*=1000000;
   628 		predictedTime+=BytesPerSecond(RecordFormatBuf())>>1;
   629 		predictedTime/=BytesPerSecond(RecordFormatBuf());
   630 		TTime starttime;
   631 		starttime.HomeTime();
   632 
   633 		// Issue a pair of record requests.
   634 		TInt vol = I64LOW(TInt64(KSoundMaxVolume)*TInt64(bytesRecorded)/TInt64(bytesToRecord));
   635 		RxSoundDevice.SetVolume(vol);
   636 		RxSoundDevice.RecordData(stat[0],length[0]);
   637 		RxSoundDevice.RecordData(stat[1],length[1]);
   638 		TInt currentReq=0;
   639 
   640 		TInt retOffset;
   641 		do
   642 			{
   643 			// Wait for the next expected request to complete.
   644 			User::WaitForRequest(stat[currentReq]);
   645 			remainingRecordCount--;
   646 			retOffset=stat[currentReq].Int();
   647 			CHECK_POSITIVE(retOffset);
   648 
   649 			CHECK(length[currentReq]>0);
   650 			bytesRecorded += length[currentReq];
   651 
   652 			r=RxSoundDevice.ReleaseBuffer(retOffset);
   653 			CHECK_NOERROR(r);
   654 			CHECK_EQUAL(RxSoundDevice.Volume(),vol);
   655 			CHECK_EQUAL(RxSoundDevice.SetAudioFormat(RecordFormatBuf),KErrInUse);
   656 
   657 			vol = I64LOW(TInt64(KSoundMaxVolume)*TInt64(bytesRecorded)/TInt64(bytesToRecord));
   658 			RxSoundDevice.SetVolume(vol);
   659 
   660 			// Don't issue any further record requests on the last two loop passes - to allow for the
   661 			// two record requests made before the loop started.
   662 			if (remainingRecordCount>=2)
   663 				RxSoundDevice.RecordData(stat[currentReq],length[currentReq]);
   664 
   665 			currentReq^=0x01;	// Toggle the current req. indicator
   666 			}
   667 		while(remainingRecordCount>0);
   668 
   669 		TTime endtime;
   670 		endtime.HomeTime();
   671 		TInt64 elapsedTime = endtime.Int64()-starttime.Int64();	// us
   672 		Test.Printf(_L("Recorded %d bytes in %d us\n"),bytesRecorded, I64LOW(elapsedTime));
   673 		if (elapsedTime < predictedTime)
   674 			{
   675 			Test.Printf(_L("**** FAIL: time travelling; record took less time than it could have done\n"));
   676 			// CHECK_NOERROR(1);
   677 			}
   678 		CHECK_EQUAL(bytesToRecord,bytesRecorded);
   679 		Test.Printf(_L("Sample rate successful\r\n"));
   680 
   681 		RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
   682 		chunk.Close();
   683 		}
   684 	}
   685 
   686 /**	@SYMTestCaseID 			PBASE-T_SOUND2-253
   687 	@SYMTestCaseDesc 		Record operation - altering the record level.
   688 	@SYMTestPriority 		Critical
   689 	@SYMTestActions			Setup the audio configuration on the record channel and then setup the buffer configuration
   690 							so it contains multiple buffers. Using multiple simultaneous record requests, record 10
   691 							seconds of audio data - with each individual record request being for 1/8th second of data.
   692 							Each time a request completes, increase the record level slightly - starting at the minimum
   693 							and ending at maximum record level.
   694 	@SYMTestExpectedResults	The driver should successfully record 10 seconds of data - i.e. all requests should complete
   695 							with KErrNone.
   696 	@SYMREQ					PREQ1073.4
   697 */
   698 LOCAL_C void TestRecordVolume(TInt aNumChannels,TInt aNumSeconds)
   699 	{
   700 	TRequestStatus stat[2];
   701 	TInt length[2];
   702 	TInt r, i;
   703 
   704 	Test.Next(_L("Preparing to test variable record levels..."));
   705 
   706 	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   707 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   708 
   709 	RecordFormatBuf().iChannels = aNumChannels;
   710 
   711 	// find first supported rate and set the the audio configuration to use it
   712 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
   713 		{
   714 		RecordFormatBuf().iRate = (TSoundRate)i;
   715 		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
   716 		if (RecordCapsBuf().iRates & (1<<i))
   717 			{
   718 			CHECK_NOERROR(r);				// Caps reports it is supported
   719 			break;
   720 			}
   721 		}
   722 	PrintConfig(RecordFormatBuf(),Test);
   723 
   724 	// Set the record buffer configuration, then read it back.
   725 	RChunk chunk;
   726 	TInt bufSize=BytesPerSecond(RecordFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
   727 	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());	// Keep the buffer length valid for driver.
   728 	TTestSharedChunkBufConfig bufferConfig;
   729 	bufferConfig.iNumBuffers=8;
   730 	bufferConfig.iBufferSizeInBytes=bufSize;
   731 	bufferConfig.iFlags=0;																// All buffers will be contiguous
   732 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   733 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   734 	CHECK_NOERROR(r);
   735 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
   736 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
   737 
   738 	Test.Next(_L("Recording..."));
   739 	TInt remainingRecordCount = BytesPerSecond(RecordFormatBuf())*aNumSeconds/bufSize;
   740 	TInt bytesToRecord = remainingRecordCount*bufSize;
   741 	TInt bytesRecorded = 0;
   742 
   743 	// Issue a pair of record requests.
   744 	RxSoundDevice.SetVolume(KSoundMaxVolume);
   745 	RxSoundDevice.RecordData(stat[0],length[0]);
   746 	RxSoundDevice.RecordData(stat[1],length[1]);
   747 	TInt currentReq=0;
   748 
   749 	TInt retOffset;
   750 	do
   751 		{
   752 		// Adjust the record level.
   753 		TInt vol = I64LOW(TInt64(KSoundMaxVolume)*TInt64(bytesRecorded)/TInt64(bytesToRecord));
   754 		r=RxSoundDevice.SetVolume(vol);
   755 		CHECK_NOERROR(r);
   756 
   757 		// Wait for the next expected request to complete.
   758 		User::WaitForRequest(stat[currentReq]);
   759 		remainingRecordCount--;
   760 		retOffset=stat[currentReq].Int();
   761 		CHECK_POSITIVE(retOffset);
   762 
   763 		// Check the length recorded and update bytes recorded.
   764 		CHECK(length[currentReq]>0);
   765 		bytesRecorded += length[currentReq];
   766 		Test.Printf(_L("."));
   767 
   768 		// Read back the record level / check we can't reconfig while recording.
   769 		CHECK_EQUAL(RxSoundDevice.Volume(),vol);
   770 		CHECK_EQUAL(RxSoundDevice.SetAudioFormat(RecordFormatBuf),KErrInUse);
   771 
   772 		// Now release the buffer and issue another record request.
   773 		r=RxSoundDevice.ReleaseBuffer(retOffset);
   774 		CHECK_NOERROR(r);
   775 		// Don't issue any further record requests on the last two loop passes - to allow for the
   776 		// two record requests made before the loop started.
   777 		if (remainingRecordCount>=2)
   778 			RxSoundDevice.RecordData(stat[currentReq],length[currentReq]);
   779 
   780 		currentReq^=0x01;	// Toggle the current req. indicator
   781 		}
   782 	while(remainingRecordCount>0);
   783 
   784 	CHECK_EQUAL(bytesToRecord,bytesRecorded);
   785 
   786 	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
   787 	Test.Printf(_L("\nBytes recorded = %d\r\n"),bytesRecorded);
   788 	chunk.Close();
   789 	}
   790 
   791 /**	@SYMTestCaseID 			PBASE-T_SOUND2-245
   792 	@SYMTestCaseDesc 		Play operation - play cancellation.
   793 	@SYMTestPriority 		Critical
   794 	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer configuration
   795 							so it contains two buffers.
   796 							1)	Issue two simultaneous play requests, one from each buffer, each of 1/2 second of tone.
   797 								Wait for the first one to complete and issue a further play request from the same buffer.
   798 								Then immediately cancel all outstanding play requests (using CancelPlayData()).
   799 							2)	Issue two simultaneous play requests, one from each buffer, each of 1/2 second of tone.
   800 								Wait for the first one to complete and issue a further play request from the same buffer.
   801 								Then immediately cancel the 2nd (i.e. now active) play request (using Cancel()).
   802 	@SYMTestExpectedResults	1)	Both outstanding requests should complete, either with KErrNone or with KErrCancel.
   803 							2)	The second request should complete, either with KErrNone or with KErrCancel whereas the
   804 								third should complete only with KErrNone.
   805 	@SYMREQ					PREQ1073.4
   806 */
   807 LOCAL_C void TestPlayCancel()
   808 	{
   809 	TRequestStatus stat[2];
   810 	TPtr8* tPtr[2];
   811 	TInt i, r;
   812 	for (i=0;i<2;i++)
   813 		tPtr[i]=new TPtr8(NULL,0);
   814 
   815 	Test.Next(_L("Test play cancellation"));
   816 
   817 	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   818 		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   819 	PlayFormatBuf().iChannels = 2;
   820 
   821 	// find first supported rate and set the the audio configuration to use it
   822 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
   823 		{
   824 		// check record channel
   825 		PlayFormatBuf().iRate = (TSoundRate)i;
   826 		r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
   827 		if (PlayCapsBuf().iRates & (1 << i))
   828 			{
   829 			CHECK_NOERROR(r);		// Caps reports it is supported
   830 			break;
   831 			}
   832 		}
   833 	PrintConfig(PlayFormatBuf(),Test);
   834 	r=MakeSineTable(PlayFormatBuf());
   835 	CHECK_NOERROR(r);
   836 
   837 	// Set the play buffer configuration, then read it back.
   838 	RChunk chunk;
   839 	TInt bufSize=BytesPerSecond(PlayFormatBuf())/2; 									// Large enough to hold 1/2 second of data.
   840 	bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
   841 	TTestSharedChunkBufConfig bufferConfig;
   842 	bufferConfig.iNumBuffers=2;
   843 	bufferConfig.iBufferSizeInBytes=bufSize;
   844 	bufferConfig.iFlags=0;																// All buffers will be contiguous
   845 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   846 	r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   847 	CHECK_NOERROR(r);
   848 	TxSoundDevice.GetBufferConfig(bufferConfigBuf);
   849 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
   850 	tPtr[0]->Set(chunk.Base()+bufferConfig.iBufferOffsetList[0],0,bufSize);
   851 	tPtr[1]->Set(chunk.Base()+bufferConfig.iBufferOffsetList[1],0,bufSize);
   852 
   853 	Test.Next(_L("Test cancelling all outstanding requests"));
   854 	// Issue a pair of play requests.
   855 	r=SetToneFrequency(440,PlayFormatBuf());
   856 	CHECK_NOERROR(r);
   857 	WriteTone(*tPtr[0],PlayFormatBuf());
   858 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize);
   859 	WriteTone(*tPtr[1],PlayFormatBuf());
   860 	TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],bufSize);
   861 
   862 	// Wait for the 1st request to complete. Then, re-queue a further request but then
   863 	// immediately cancel both requests.
   864 	User::WaitForRequest(stat[0]);
   865 	CHECK_NOERROR(stat[0].Int());
   866 	WriteTone(*tPtr[0],PlayFormatBuf());
   867 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize);
   868 	TxSoundDevice.CancelPlayData();
   869 
   870 	User::WaitForRequest(stat[1]);
   871 	if (stat[1]==KErrNone)
   872 		Test.Printf(_L("Note: 2nd request finished without cancel error\r\n"));
   873 	else
   874 		CHECK_EQUAL(stat[1].Int(),KErrCancel);
   875 	User::WaitForRequest(stat[0]);
   876 	if (stat[0]==KErrNone)
   877 		Test.Printf(_L("Note: 3rd request finished without cancel error\r\n"));
   878 	else
   879 		CHECK_EQUAL(stat[0].Int(),KErrCancel);
   880 
   881 	Test.Next(_L("Test cancelling an individual requests"));
   882 	// Issue a further pair of play requests.
   883 	r=SetToneFrequency(440,PlayFormatBuf());
   884 	CHECK_NOERROR(r);
   885 	WriteTone(*tPtr[0],PlayFormatBuf());
   886 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,0);
   887 	WriteTone(*tPtr[1],PlayFormatBuf());
   888 	TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],bufSize,0);
   889 
   890 	// Again, wait for the 1st request to complete. Then, re-queue a further request but then
   891 	// immediately cancel the 2nd request.
   892 	User::WaitForRequest(stat[0]);
   893 	CHECK_NOERROR(stat[0].Int());
   894 	WriteTone(*tPtr[0],PlayFormatBuf());
   895 	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
   896 	TxSoundDevice.Cancel(stat[1]);
   897 
   898 	User::WaitForRequest(stat[1]);
   899 	if (stat[1]==KErrNone)
   900 		Test.Printf(_L("Note: 2nd request finished without cancel error\r\n"));
   901 	else
   902 		CHECK_EQUAL(stat[1].Int(),KErrCancel);
   903 	User::WaitForRequest(stat[0]);
   904 	CHECK_NOERROR(stat[0].Int());
   905 
   906 	chunk.Close();
   907 	Test.Printf(_L("Cancel play test completed successful\r\n"));
   908 
   909 	for (i=0;i<2;i++)
   910 		delete tPtr[i];
   911 	}
   912 
   913 /**	@SYMTestCaseID 			PBASE-T_SOUND2-259
   914 	@SYMTestCaseDesc 		Record operation - record cancellation.
   915 	@SYMTestPriority 		Critical
   916 	@SYMTestActions			Setup the audio configuration on the record channel and then setup the buffer configuration
   917 							so it contains multiple buffers.
   918 							1)	Issue two simultaneous record requests requests, each for 1/2 second of data. Wait for
   919 								the first one to complete and issue a further record request. Then immediately cancel all
   920 								outstanding record requests (using CancelRecordData()).
   921 							2)	Issue two simultaneous record requests, each for 1/2 second of data. Wait for the first
   922 								one to complete and issue a further record request. Then immediately cancel the 2nd (i.e.
   923 								now active) record request (using Cancel()).
   924 	@SYMTestExpectedResults	1)	Both outstanding requests should complete, either with KErrNone or with KErrCancel.
   925 							2)	The second requests should complete, either with KErrNone or with KErrCancel whereas the
   926 								third should complete only with KErrNone.
   927 	@SYMREQ					PREQ1073.4
   928 */
   929 LOCAL_C void TestRecordCancel()
   930 	{
   931 	TRequestStatus stat[2];
   932 	TInt length[2];
   933 	TPtr8* tPtr[2];
   934 	TInt i, r;
   935 	for (i=0;i<2;i++)
   936 		tPtr[i]=new TPtr8(NULL,0);
   937 
   938 	Test.Next(_L("Test record cancellation"));
   939 
   940 	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
   941 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
   942 	RecordFormatBuf().iChannels = 2;
   943 
   944 	// find first supported rate and set the the audio configuration to use it
   945 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
   946 		{
   947 		RecordFormatBuf().iRate = (TSoundRate)i;
   948 		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
   949 		if (RecordCapsBuf().iRates & (1<<i))
   950 			{
   951 			CHECK_NOERROR(r);				// Caps reports it is supported
   952 			break;
   953 			}
   954 		}
   955 
   956 	PrintConfig(RecordFormatBuf(),Test);
   957 
   958 	// Set the record buffer configuration, then read it back.
   959 	RChunk chunk;
   960 	TTestSharedChunkBufConfig bufferConfig;
   961 	bufferConfig.iNumBuffers=3;
   962 	bufferConfig.iBufferSizeInBytes=BytesPerSecond(RecordFormatBuf())/2; // Large enough to hold 1/2 second of data.
   963 	bufferConfig.iBufferSizeInBytes=ValidBufferSize(bufferConfig.iBufferSizeInBytes,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());		// Keep the buffer length valid for driver.
   964 	bufferConfig.iFlags=0;		// All buffers will be contiguous
   965 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   966 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
   967 	CHECK_NOERROR(r);
   968 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
   969 
   970 	Test.Next(_L("Test cancelling all outstanding requests"));
   971 	// Issue a pair of record requests.
   972 	RxSoundDevice.RecordData(stat[0],length[0]);
   973 	RxSoundDevice.RecordData(stat[1],length[1]);
   974 
   975 	// Wait for the 1st request to complete. Then, re-queue a further request but then
   976 	// immediately cancel both requests.
   977 	TInt retOffset;
   978 	User::WaitForRequest(stat[0]);
   979 	retOffset=stat[0].Int();
   980 	CHECK_POSITIVE(retOffset);
   981 	CHECK(length[0]>0);
   982 	r=RxSoundDevice.ReleaseBuffer(retOffset);
   983 	CHECK_NOERROR(r);
   984 	RxSoundDevice.RecordData(stat[0],length[0]);
   985 	RxSoundDevice.CancelRecordData();
   986 
   987 	User::WaitForRequest(stat[1]);
   988 	retOffset=stat[1].Int();
   989 	if (retOffset>=0)
   990 		Test.Printf(_L("Note: 2nd request finished without cancel error\r\n"));
   991 	else
   992 		CHECK_EQUAL(retOffset,KErrCancel);
   993 	User::WaitForRequest(stat[0]);
   994 	retOffset=stat[0].Int();
   995 	if (retOffset>=0)
   996 		Test.Printf(_L("Note: 3rd request finished without cancel error\r\n"));
   997 	else
   998 		CHECK_EQUAL(retOffset,KErrCancel);
   999 
  1000 	Test.Next(_L("Test cancelling an individual requests"));
  1001 	// Issue a further pair of record requests.
  1002 	RxSoundDevice.RecordData(stat[0],length[0]);
  1003 	RxSoundDevice.RecordData(stat[1],length[1]);
  1004 
  1005 	// Again, wait for the 1st request to complete. Then, re-queue a further request but then
  1006 	// immediately cancel the 2nd request.
  1007 	User::WaitForRequest(stat[0]);
  1008 	retOffset=stat[0].Int();
  1009 	CHECK_POSITIVE(retOffset);
  1010 	CHECK(length[0]>0);
  1011 	r=RxSoundDevice.ReleaseBuffer(retOffset);
  1012 	CHECK_NOERROR(r);
  1013 	RxSoundDevice.RecordData(stat[0],length[0]);
  1014 	RxSoundDevice.Cancel(stat[1]);
  1015 
  1016 	User::WaitForRequest(stat[1]);
  1017 	retOffset=stat[1].Int();
  1018 	if (retOffset>=0)
  1019 		Test.Printf(_L("Note: 2nd request finished without cancel error\r\n"));
  1020 	else
  1021 		CHECK_EQUAL(retOffset,KErrCancel);
  1022 	User::WaitForRequest(stat[0]);
  1023 	retOffset=stat[0].Int();
  1024 	CHECK_POSITIVE(retOffset);
  1025 	CHECK(length[0]>0);
  1026 
  1027 	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
  1028 	chunk.Close();
  1029 	Test.Printf(_L("Cancel record test completed successful\r\n"));
  1030 
  1031 	for (i=0;i<2;i++)
  1032 		delete tPtr[i];
  1033 	}
  1034 
  1035 /**	@SYMTestCaseID 			PBASE-T_SOUND2-262
  1036 	@SYMTestCaseDesc 		Play pause / resume - pausing and resuming before playback has commenced.
  1037 	@SYMTestPriority 		Critical
  1038 	@SYMTestActions			Setup the audio configuration on the record channel and then setup the buffer configuration.
  1039 							1)	Attempt to resume recording before recording has been started.
  1040 							2)	Attempt to pause recording before recording has been started.
  1041 	@SYMTestExpectedResults	1)	The resume request should complete with KErrNotReady.
  1042 							2)	The pause request should complete with KErrNotReady.
  1043 	@SYMREQ					PREQ1073.4
  1044 */
  1045 
  1046 /**	@SYMTestCaseID 			PBASE-T_SOUND2-263
  1047 	@SYMTestCaseDesc 		Record pause / resume - pausing and resuming while recording is in progress.
  1048 	@SYMTestPriority 		Critical
  1049 	@SYMTestActions			Setup the audio configuration on the record channel and then setup the buffer configuration
  1050 							so it contains multiple buffers. For the audio configuration selected, calculate the total
  1051 							number of bytes expected to be transferred in order record 4 seconds of data. Using multiple
  1052 							simultaneous record requests, record 4 seconds of audio data - with each individual record
  1053 							request being for 1/8th second of data. Increment a count of actual total bytes transferred
  1054 							by examining the count of bytes stored in the buffer for each request as it completes.
  1055 							1) After 10 requests have completed, pause transfer for 1 second, then resume it. If pausing
  1056 							causes a record request to complete with a shorter than requested length then reduce the
  1057 							count of expected total bytes transferred.
  1058 							2) Repeat step 1 when 20 requests have completed.
  1059 							3) Once transfer has completed, compare the counts of expected and actual total bytes
  1060 							transferred.
  1061 	@SYMTestExpectedResults	1)	The pause and resume requests should both complete with KErrNone.
  1062 							2)	The pause and resume requests should both complete with KErrNone.
  1063 							3)	The counts should be equal.
  1064 	@SYMREQ					PREQ1073.4
  1065 */
  1066 LOCAL_C void TestRecordPauseResume(TUint aChannels)
  1067 	{
  1068 	TRequestStatus stat[2];
  1069 	TInt length[2];
  1070 
  1071 	Test.Next(_L("Test record pause and resume"));
  1072 	RecordFormatBuf().iRate = ESoundRate44100Hz;
  1073 	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
  1074 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1075 	RecordFormatBuf().iChannels = aChannels;
  1076 	PrintConfig(RecordFormatBuf(),Test);
  1077 	TInt r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
  1078 	CHECK_NOERROR(r);
  1079 
  1080 	// Set the record buffer configuration, then read it back.
  1081 	RChunk chunk;
  1082 	TInt bufSize=BytesPerSecond(RecordFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
  1083 	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());	// Keep the buffer length valid for driver.
  1084 	TTestSharedChunkBufConfig bufferConfig;
  1085 	bufferConfig.iNumBuffers=8;
  1086 	bufferConfig.iBufferSizeInBytes=bufSize;
  1087 	bufferConfig.iFlags=0;																// All buffers will be contiguous
  1088 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
  1089 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
  1090 	CHECK_NOERROR(r);
  1091 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
  1092 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
  1093 
  1094 	Test.Printf(_L("Resume when not recording\r\n"));
  1095 	r=RxSoundDevice.Resume();
  1096 	CHECK(r==KErrNotReady)
  1097 
  1098 	Test.Printf(_L("Pause when not recording\r\n"));
  1099 	r=RxSoundDevice.Pause();
  1100 	CHECK(r==KErrNotReady)
  1101 
  1102 	// Record for 4 seconds
  1103 	Test.Printf(_L("Record...\r\n"));
  1104 	TInt remainingRecordCount = BytesPerSecond(RecordFormatBuf())*4/bufSize;
  1105 	TInt bytesToRecord = remainingRecordCount*bufSize;
  1106 	TInt bytesRecorded = 0;
  1107 
  1108 	// Issue a pair of record requests.
  1109 	RxSoundDevice.SetVolume(KSoundMaxVolume);
  1110 	length[0] = -42;
  1111 	RxSoundDevice.RecordData(stat[0],length[0]);
  1112 	length[1] = -42;
  1113 	RxSoundDevice.RecordData(stat[1],length[1]);
  1114 	TInt currentReq=0;
  1115 
  1116 	TInt lcount = 0;
  1117 	TInt retOffset;
  1118 	do
  1119 		{
  1120 		// Do a pause / resume on 10th and 20th loop passes.
  1121 		if (lcount && !(lcount%10))
  1122 			{
  1123 			// Do a pause/resume
  1124 			Test.Printf(_L("Pause 1 second\r\n"));
  1125 			r=RxSoundDevice.Pause();
  1126 			CHECK_NOERROR(r);
  1127 
  1128 			// Pausing record may result in the driver completing with a buffer not completely full. This isn't an error. Otherwise, all outstanding
  1129 			// requests should complete with KErrCancel. Wait for the 1st outstanding request to complete.
  1130 			User::WaitForRequest(stat[currentReq]);
  1131 			retOffset=stat[currentReq].Int();
  1132 			if (retOffset>=0)
  1133 				{
  1134 				// Partially filled buffer. We need to adjust the bytes expected when an incomplete buffer arrives.
  1135 				remainingRecordCount--;
  1136 
  1137 				CHECK_POSITIVE(length[currentReq]);
  1138 				CHECK(length[currentReq]<=bufSize);
  1139 				bytesRecorded += length[currentReq];
  1140 				if (length[currentReq]<bufSize)
  1141 					bytesToRecord-=(bufSize-length[currentReq]);
  1142 				Test.Printf(_L("1st outstanding req partially completed(len=%d)\r\n"),length[currentReq]);
  1143 
  1144 				r=RxSoundDevice.ReleaseBuffer(retOffset); // Release the buffer ready for resuming
  1145 				CHECK_NOERROR(r);
  1146 				}
  1147 			else
  1148 				{
  1149 				CHECK(retOffset==KErrCancel);
  1150 				Test.Printf(_L("1st outstanding req cancelled\r\n"));
  1151 				}
  1152 			currentReq^=0x01;	// Toggle the current req. indicator
  1153 
  1154 			// Wait for the 2nd outstanding request to complete
  1155 			User::WaitForRequest(stat[currentReq]);
  1156 			retOffset=stat[currentReq].Int();
  1157 			CHECK(retOffset==KErrCancel);
  1158 			Test.Printf(_L("2nd outstanding req cancelled\r\n"));
  1159 
  1160 			// Idle for 1 second, resume and then re-issue a pair of record requests.
  1161 			User::After(1000000);
  1162 			Test.Printf(_L("Resume\r\n"));
  1163 			r=RxSoundDevice.Resume();
  1164 			CHECK_NOERROR(r);
  1165 			RxSoundDevice.RecordData(stat[0],length[0]);
  1166 			RxSoundDevice.RecordData(stat[1],length[1]);
  1167 			currentReq=0;
  1168 			}
  1169 
  1170 		// Wait for the next expected request to complete.
  1171 		User::WaitForRequest(stat[currentReq]);
  1172 		remainingRecordCount--;
  1173 		retOffset=stat[currentReq].Int();
  1174 		CHECK_POSITIVE(retOffset);
  1175 		CHECK(length[currentReq]>0);
  1176 		bytesRecorded += length[currentReq];
  1177 
  1178 		// Now release the buffer and issue another record request
  1179 		r=RxSoundDevice.ReleaseBuffer(retOffset);
  1180 		CHECK_NOERROR(r);
  1181 		// Don't issue any further record requests on the last two loop passes - to allow for the
  1182 		// two record requests made before the loop started.
  1183 		if (remainingRecordCount>=2)
  1184 			RxSoundDevice.RecordData(stat[currentReq],length[currentReq]);
  1185 		lcount++;
  1186 		currentReq^=0x01;	// Toggle the current req. indicator
  1187 		}
  1188 	while(remainingRecordCount>0);
  1189 
  1190 	CHECK_EQUAL(bytesToRecord,bytesRecorded);
  1191 	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
  1192 	Test.Printf(_L("Record pause/resume successful\r\n"));
  1193 
  1194 	Test.Next(_L("Test record pause alone"));
  1195 
  1196 	// Issue a single record request, wait for it to complete and then release it.
  1197 	RxSoundDevice.RecordData(stat[0],length[0]);
  1198 	User::WaitForRequest(stat[0]);
  1199 	retOffset=stat[0].Int();
  1200 	CHECK_POSITIVE(retOffset);
  1201 	CHECK(length[0]==bufSize);
  1202 	r=RxSoundDevice.ReleaseBuffer(retOffset);
  1203 	CHECK_NOERROR(r);
  1204 
  1205 	// Without issuing another record request, wait for a duration equal to one record buffer, then pause.
  1206 	User::After(150000);	// Wait a bit longer than 1 buffer's worth (125000 is 1/8 second).
  1207 	Test.Printf(_L("Pause\r\n"));
  1208 	r=RxSoundDevice.Pause();
  1209 	CHECK_NOERROR(r);
  1210 
  1211 	// Check that there is at least 1 buffer's worth of record data available
  1212 	RxSoundDevice.RecordData(stat[0],length[0]);
  1213 	User::WaitForRequest(stat[0]);
  1214 	retOffset=stat[0].Int();
  1215 	CHECK_POSITIVE(retOffset);
  1216 	CHECK(length[0]==bufSize);
  1217 	Test.Printf(_L("1st req completed successfully\r\n"));
  1218 	r=RxSoundDevice.ReleaseBuffer(retOffset);
  1219 	CHECK_NOERROR(r);
  1220 
  1221 	// There's probably also a partially filled buffer
  1222 	RxSoundDevice.RecordData(stat[0],length[0]);
  1223 	User::WaitForRequest(stat[0]);
  1224 	retOffset=stat[0].Int();
  1225 	if (retOffset>=0)
  1226 		{
  1227 		// Partially filled buffer.
  1228 		CHECK(length[0]>0);
  1229 		CHECK(length[0] <= bufSize);
  1230 		Test.Printf(_L("2nd req partially completed(len=%d)\r\n"),length[0]);
  1231 		r=RxSoundDevice.ReleaseBuffer(retOffset);
  1232 		CHECK_NOERROR(r);
  1233 		}
  1234 	else
  1235 		{
  1236 		CHECK(retOffset==KErrCancel);
  1237 		Test.Printf(_L("2nd req cancelled\r\n"));
  1238 		}
  1239 
  1240 	for(;;)
  1241 		{
  1242 		// Read all buffers until driver is empty. The RecordData call after that should immediately return with KErrCancel
  1243 		Test.Printf(_L("Draining driver\r\n"));
  1244 		RxSoundDevice.RecordData(stat[0],length[0]);
  1245 		User::WaitForRequest(stat[0]);
  1246 		retOffset=stat[0].Int();
  1247 		if(retOffset==KErrCancel)
  1248 			{
  1249 			break;
  1250 			}
  1251 		CHECK_NOERROR(retOffset);
  1252 		}
  1253 	Test.Printf(_L("Driver empty\r\n"));
  1254 
  1255 	r=RxSoundDevice.Resume();			// Don't leave it in paused state.
  1256 	CHECK_NOERROR(r);
  1257 	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
  1258 	Test.Printf(_L("Record pause successful\r\n"));
  1259 
  1260 	chunk.Close();
  1261 	}
  1262 
  1263 template <class T>
  1264 class RQueue
  1265     {
  1266 public:
  1267     RQueue() 
  1268         : iArray() 
  1269         { }
  1270     void Close() 
  1271         { 
  1272         iArray.Close(); 
  1273         }
  1274     TInt Count() const 
  1275         { 
  1276         return iArray.Count(); 
  1277         }
  1278     void PushL(const T &aItem) 
  1279         {
  1280         iArray.AppendL(aItem); 
  1281         }
  1282     T PopL()
  1283         {
  1284         if(iArray.Count() == 0)
  1285             {
  1286             User::Leave(KErrUnderflow);
  1287             }
  1288         const T ret = iArray[0];
  1289         iArray.Remove(0);
  1290         return ret;
  1291         }
  1292 private:
  1293     RArray<T> iArray;
  1294     };
  1295 /**	@SYMTestCaseID 			PBASE-T_SOUND2-248
  1296 	@SYMTestCaseDesc 		Play operation - simultaneous play and record on the same device, using a common shared chunk.
  1297 	@SYMTestPriority 		Critical
  1298 	@SYMTestActions			Setup the audio configuration on the record channel and setup an identical audio
  1299 							configuration on the playback channel. On the record channel, create a shared chunk
  1300 							(i.e. using SetBufferChunkCreate()) with a buffer configuration containing multiple buffers.
  1301 							Open the same shared chunk on the playback channel (i.e. using SetBufferChunkOpen()).
  1302 							Set the volume to maximum level in both channels. Record 10 seconds of audio data - with
  1303 							each individual record request being for 1/8th second of data. As soon as each record request
  1304 							completes, issue a corresponding request on the playback channel to playback the
  1305 							1/8th second of data recorded. Only release each buffer for further recording once its
  1306 							contents have been played back. Continue until 10 seconds of audio data has been both
  1307 							recorded and played back. (Ensure the last play request is marked with the
  1308 							KSndFlagLastSample flag).
  1309 	@SYMTestExpectedResults	The driver should successfully record and play 10 seconds of data - with all requests
  1310 							completing with KErrNone.
  1311 	@SYMREQ					PREQ1073.4
  1312 */
  1313 void TestSimultaneousPlayRecord()
  1314 	{
  1315 	Test.Next(_L("Preparing to record/play simultaneously..."));
  1316 	TInt r = KErrNone;
  1317 	TInt i;
  1318 	// Setup the same sound configuration for both - record and play channels
  1319 	if (RecordCapsBuf().iEncodings & KSoundEncoding16BitPCM)
  1320 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1321 
  1322 	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
  1323 		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1324 
  1325 	RecordFormatBuf().iChannels = 2;
  1326 	PlayFormatBuf().iChannels = 2;
  1327 
  1328 	// find first supported rate and set the the audio configuration to use it
  1329 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
  1330 		{
  1331 		// check record channel
  1332 		RecordFormatBuf().iRate = (TSoundRate)i;
  1333 		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
  1334 		if (RecordCapsBuf().iRates & (1 << i))
  1335 			{
  1336 			CHECK_NOERROR(r);		// Caps reports it is supported
  1337 
  1338 			// ..and try the same bitrate for playback
  1339 			PlayFormatBuf().iRate = (TSoundRate)i;
  1340 			r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
  1341 			if (PlayCapsBuf().iRates & (1 << i))
  1342 				{
  1343 				CHECK_NOERROR(r);		// Caps reports it is supported
  1344 				break;
  1345 				}
  1346 			}
  1347 		}
  1348 
  1349 	// both channels are set at this point, continue
  1350 	PrintConfig(RecordFormatBuf(),Test);
  1351 	PrintConfig(PlayFormatBuf(),Test);
  1352 
  1353 	// Set the volume level in both channels
  1354 	RxSoundDevice.SetVolume(KSoundMaxVolume);
  1355 	TxSoundDevice.SetVolume(KSoundMaxVolume - 10);
  1356 
  1357 	// Set the record buffer configuration, then read it back.
  1358 	RChunk chunk;
  1359 	TInt bufSize=BytesPerSecond(RecordFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
  1360 	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());	// Keep the buffer length valid for driver.
  1361 	TTestSharedChunkBufConfig bufferConfig;
  1362 	bufferConfig.iNumBuffers=7+7;														// Must be able to use less than this
  1363 	bufferConfig.iBufferSizeInBytes=bufSize;
  1364 	bufferConfig.iFlags=0;																// All buffers will be contiguous
  1365 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
  1366 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
  1367 	CHECK_NOERROR(r);
  1368 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
  1369 	PrintBufferConf(bufferConfig,Test);
  1370 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
  1371 
  1372 	// Assign the same chunk to the play channel.
  1373 	r=TxSoundDevice.SetBufferChunkOpen(bufferConfigBuf,chunk);
  1374 	CHECK_NOERROR(r);
  1375 
  1376 	Test.Next(_L("Starting transfer..."));
  1377 	TInt remainingRecordCount = BytesPerSecond(RecordFormatBuf())*10/bufSize; // 10 seconds
  1378 	TInt remainingPlayCount = remainingRecordCount;
  1379 	TInt bytesToTransfer = remainingRecordCount*bufSize;
  1380 	TInt bytesRecorded = 0;
  1381 	TInt bytesPlayed = 0;
  1382 
  1383 	TRequestStatus stat[3]; 	// 1 record + 2 play request statuses
  1384 	TInt length;
  1385 	TInt activePlayOffset[2];	// To keep track of the buffer offset for each active play request.
  1386 	RQueue<TInt> playQueue; // A list containing the offsets for any buffer which is waiting to be played.
  1387 
  1388 	// Issue three record requests and wait for them to complete.
  1389 	TInt retOffset;
  1390 	for (i=0 ; i<3 ; i++)
  1391 		{
  1392 		RxSoundDevice.RecordData(stat[2],length);
  1393 		User::WaitForRequest(stat[2]);
  1394 		retOffset=stat[2].Int();
  1395 //		Test.Printf(_L("RECORD(%d)-Buf %d\r\n"),i,retOffset);
  1396 		CHECK_POSITIVE(retOffset);
  1397 		CHECK(length==bufSize);
  1398 		bytesRecorded += length;
  1399 		playQueue.PushL(retOffset);
  1400 		remainingRecordCount--;
  1401 		Test.Printf(_L("."));
  1402 		}
  1403 
  1404 	// Start playing first two buffers
  1405 	TUint flags=0;
  1406 	activePlayOffset[0]=playQueue.PopL();
  1407 	TxSoundDevice.PlayData(stat[0],activePlayOffset[0],bufSize,flags);
  1408 	activePlayOffset[1]=playQueue.PopL();
  1409 	TxSoundDevice.PlayData(stat[1],activePlayOffset[1],bufSize,flags);
  1410 
  1411 	// Now queue the next record request.
  1412 	RxSoundDevice.RecordData(stat[2],length);
  1413 
  1414 	do
  1415 		{
  1416 		// Wait for the next request to complete.
  1417 		User::WaitForAnyRequest();
  1418 
  1419 		// Work out which request this applies to.
  1420 		for (i=0;i<3;i++)
  1421 			{
  1422 			if (stat[i]!=KRequestPending)
  1423 				break;
  1424 			}
  1425 		CHECK(i<3);
  1426 
  1427 		if (i==2)
  1428 			{
  1429 			// It is the record request that has completed
  1430 			remainingRecordCount--;
  1431 			retOffset=stat[2].Int();
  1432 //			Test.Printf(_L("RECORD(%d)-Buf %d\r\n"),remainingRecordCount,retOffset);
  1433 			CHECK_POSITIVE(retOffset);
  1434 			CHECK(length==bufSize);
  1435 			bytesRecorded += length;
  1436 			Test.Printf(_L("."));
  1437 
  1438 			// Add the buffer to playQueue
  1439 			playQueue.PushL(retOffset);
  1440 
  1441 			// If we haven't recorded enough data yet then record some more.
  1442 			if (remainingRecordCount>0)
  1443 				RxSoundDevice.RecordData(stat[2],length);
  1444 			else
  1445 				{
  1446 				Test.Printf(_L("***Disabling stat[2]\r\n"));
  1447 				stat[2]=KRequestPending;
  1448 				}
  1449 			}
  1450 		else
  1451 			{
  1452 			// Its one of the play requests that have completed
  1453 			if(stat[i].Int() >= 0)
  1454 				{
  1455 				// release the buffer.
  1456 //				Test.Printf(_L("PLAY(%d) i%d CompBuf %d\r\n"),remainingPlayCount-1,i,activePlayOffset[i]);
  1457 				r=RxSoundDevice.ReleaseBuffer(activePlayOffset[i]);
  1458 				CHECK_NOERROR(r);
  1459 				Test.Printf(_L("*"));
  1460 				}
  1461 			else
  1462 				{
  1463 				// Play failed - but we ignore underflow because it often happens on WDP roms.
  1464 				CHECK(stat[i].Int() == KErrUnderflow);
  1465 				Test.Printf(_L("U"));
  1466 				}
  1467 
  1468 			remainingPlayCount--;
  1469 			bytesPlayed += bufSize;
  1470 
  1471 			// If there are buffers available then issue a further play request and update the 'next to play' list.
  1472 			if (playQueue.Count() != 0)
  1473 				{
  1474 				activePlayOffset[i]=playQueue.PopL();
  1475 
  1476 //				Test.Printf(_L("PLAY(%d) i%d NextBuf%d\r\n"),remainingPlayCount,i,activePlayOffset[i]);
  1477 				flags=(remainingPlayCount<=2)?KSndFlagLastSample:0;
  1478 				TxSoundDevice.PlayData(stat[i],activePlayOffset[i],bufSize,flags);
  1479 				}
  1480 			else
  1481 				{
  1482 				Test.Printf(_L("***Disabling stat[%d]\r\n"), i, stat[i].Int());
  1483 				stat[i]=KRequestPending;
  1484 				}
  1485 			}
  1486 		}
  1487 	while (remainingRecordCount>0 || remainingPlayCount>0);
  1488 	playQueue.Close();
  1489 	CHECK_EQUAL(bytesToTransfer,bytesRecorded);
  1490 	CHECK_EQUAL(bytesToTransfer,bytesPlayed);
  1491 
  1492 	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
  1493 	chunk.Close();
  1494 
  1495 	Test.Printf(_L("\nSimultaneous test ends\r\n"));
  1496 	return;
  1497 	}
  1498 
  1499 void TestSpeed()
  1500 	{
  1501 	Test.Next(_L("Preparing to measure record/playback speed..."));
  1502 	TInt r = KErrNone;
  1503 	TInt i;
  1504 	// Setup the same sound configuration for both - record and play channels
  1505 	if (RecordCapsBuf().iEncodings & KSoundEncoding16BitPCM)
  1506 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1507 
  1508 	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
  1509 		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1510 
  1511 	RecordFormatBuf().iChannels = 2;
  1512 	PlayFormatBuf().iChannels = 2;
  1513 
  1514 	// find first supported rate and set the the audio configuration to use it
  1515 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
  1516 		{
  1517 		// check record channel
  1518 		RecordFormatBuf().iRate = (TSoundRate)i;
  1519 		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
  1520 		if (RecordCapsBuf().iRates & (1 << i))
  1521 			{
  1522 			CHECK_NOERROR(r);		// Caps reports it is supported
  1523 
  1524 			// ..and try the same bitrate for playback
  1525 			PlayFormatBuf().iRate = (TSoundRate)i;
  1526 			r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
  1527 			if (PlayCapsBuf().iRates & (1 << i))
  1528 				{
  1529 				CHECK_NOERROR(r);		// Caps reports it is supported
  1530 				break;
  1531 				}
  1532 			}
  1533 		}
  1534 
  1535 	// both channels are set at this point, continue
  1536 	PrintConfig(RecordFormatBuf(),Test);
  1537 	PrintConfig(PlayFormatBuf(),Test);
  1538 
  1539 	// Set the volume level in both channels
  1540 	RxSoundDevice.SetVolume(KSoundMaxVolume);
  1541 	TxSoundDevice.SetVolume(KSoundMaxVolume - 10);
  1542 
  1543 	// Set the record buffer configuration, then read it back.
  1544 	RChunk chunk;
  1545 	TInt bufSize=BytesPerSecond(RecordFormatBuf())/8; 									// Large enough to hold 1/8th second of data.
  1546 	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());	// Keep the buffer length valid for driver.
  1547 	TTestSharedChunkBufConfig bufferConfig;
  1548 	bufferConfig.iNumBuffers=7+7;															// Must be able to use less than this
  1549 	bufferConfig.iBufferSizeInBytes=bufSize;
  1550 	bufferConfig.iFlags=0;																// All buffers will be contiguous
  1551 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
  1552 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
  1553 	CHECK_NOERROR(r);
  1554 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
  1555 	PrintBufferConf(bufferConfig,Test);
  1556 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
  1557 
  1558 	// Assign the same chunk to the play channel.
  1559 	r=TxSoundDevice.SetBufferChunkOpen(bufferConfigBuf,chunk);
  1560 	CHECK_NOERROR(r);
  1561 
  1562 	Test.Next(_L("Starting recording speed test..."));
  1563 	TInt length;
  1564 
  1565 	// Recording speed test
  1566 	TTime preTime, postTime;
  1567 	preTime.UniversalTime();
  1568 	for(i=0; i<100; ++i)
  1569 		{
  1570 		TRequestStatus s;
  1571 		length = -1;
  1572 		
  1573 		TTime preBufTime, postBufTime;
  1574 		preBufTime.UniversalTime();
  1575 		RxSoundDevice.RecordData(s, length);
  1576 		User::WaitForRequest(s);
  1577 		
  1578 		postBufTime.UniversalTime();
  1579 		TTimeIntervalMicroSeconds elapsedBufTime = postBufTime.MicroSecondsFrom(preBufTime);
  1580 		Test.Printf(_L("\tElapsed buf (%d/100) recording time %d\n"), i, elapsedBufTime.Int64());
  1581 		CHECK(s.Int() >= 0);
  1582 		CHECK(RxSoundDevice.ReleaseBuffer(s.Int()) == KErrNone);
  1583 		CHECK(length == bufSize);
  1584 		}
  1585 	postTime.UniversalTime();
  1586 	TTimeIntervalMicroSeconds elapsedRecordingTime = postTime.MicroSecondsFrom(preTime);
  1587 	Test.Printf(_L("Elapsed recording time %d\n"), elapsedRecordingTime.Int64());
  1588 	Test.Printf(_L("Record timing done\n"));
  1589 
  1590 
  1591 	//
  1592 	// Playback test
  1593 	//
  1594 	TxSoundDevice.CancelPlayData();
  1595 	struct RequestInfo {
  1596 		TRequestStatus s_m;
  1597 		TUint bufOffset_m;
  1598 		};
  1599 	RequestInfo requestA;
  1600 	RequestInfo requestB;
  1601 	
  1602 	// Get two buffers for playback speed test
  1603 	RxSoundDevice.RecordData(requestA.s_m, length);
  1604 	User::WaitForRequest(requestA.s_m);
  1605 	CHECK(requestA.s_m.Int() >= 0);
  1606 	requestA.bufOffset_m = requestA.s_m.Int();
  1607 
  1608     RxSoundDevice.RecordData(requestB.s_m, length);
  1609     User::WaitForRequest(requestB.s_m);
  1610     CHECK(requestB.s_m.Int() >= 0);
  1611     requestB.bufOffset_m = requestB.s_m.Int();
  1612 
  1613     Test.Printf(_L("buf offsets %d %d\n"), requestA.bufOffset_m, requestB.bufOffset_m);
  1614 	
  1615 	RequestInfo *prevRequest = &requestA;
  1616 	RequestInfo *currRequest = &requestB;
  1617 
  1618 	// Issue initial play request
  1619 	TxSoundDevice.PlayData(prevRequest->s_m, prevRequest->bufOffset_m, bufSize);
  1620 
  1621 	preTime.UniversalTime();
  1622 	for(i=0; i<100; ++i)
  1623 		{
  1624 		// Issue new request so we do not underflow....
  1625 		TxSoundDevice.PlayData(currRequest->s_m, currRequest->bufOffset_m, bufSize, (i==99)?(KSndFlagLastSample) : (0));
  1626 
  1627 		// Wait for previous request to complete
  1628 		TTime preBufTime, postBufTime;
  1629 		preBufTime.UniversalTime();
  1630 		User::WaitForRequest(prevRequest->s_m);
  1631 		CHECK_NOERROR(prevRequest->s_m.Int());
  1632 
  1633 		postBufTime.UniversalTime();
  1634 		TTimeIntervalMicroSeconds elapsedBufTime = postBufTime.MicroSecondsFrom(preBufTime);
  1635 		Test.Printf(_L("\tElapsed buf (%d/100) playback time %d\n"), i, elapsedBufTime.Int64());
  1636 
  1637 		// Swap previous and current requests
  1638 		RequestInfo *p = prevRequest;
  1639 		prevRequest = currRequest;
  1640 		currRequest = p;
  1641 		}
  1642 	
  1643 	postTime.UniversalTime();
  1644 	TTimeIntervalMicroSeconds elapsedPlaybackTime = postTime.MicroSecondsFrom(preTime);
  1645     Test.Printf(_L("Elapsed playback time  = %d us\n"), elapsedPlaybackTime.Int64());
  1646     Test.Printf(_L("Elapsed recording time = %d us\n"), elapsedRecordingTime.Int64());
  1647 	
  1648 	double play = (double) elapsedPlaybackTime.Int64();
  1649 	double record = (double) elapsedRecordingTime.Int64();
  1650 	Test.Printf(_L("difference %f%%\n"), (play*100)/record);
  1651 	
  1652 	User::WaitForRequest(prevRequest->s_m);
  1653 	CHECK_NOERROR(prevRequest->s_m.Int());
  1654 
  1655     // Free the two buffers
  1656     CHECK(RxSoundDevice.ReleaseBuffer(requestA.bufOffset_m) == KErrNone);
  1657     CHECK(RxSoundDevice.ReleaseBuffer(requestB.bufOffset_m) == KErrNone);
  1658  
  1659 	Test.Printf(_L("Playback done\n"));
  1660     TxSoundDevice.CancelPlayData();
  1661     RxSoundDevice.CancelPlayData();
  1662 
  1663 	chunk.Close();
  1664 	return;		
  1665 }
  1666 
  1667 #ifdef __WINS__
  1668 void TestDefectDTWMM00678()
  1669 {
  1670 	// DTW-MM00678  RSoundSc::RecordData() returns recorded length > allocated buffer size 
  1671     TRequestStatus status[3];
  1672     TInt length[3];
  1673 	Test.Next(_L("DTW-MM00678  RSoundSc::RecordData() returns recorded length > allocated buffer size"));
  1674 
  1675 	// Make sure recording is not in progress
  1676 	RxSoundDevice.CancelRecordData();
  1677 
  1678 	TInt r = KErrNone;
  1679 	TInt i;
  1680 	// Setup the same sound configuration for both - record and play channels
  1681 	if (RecordCapsBuf().iEncodings & KSoundEncoding16BitPCM)
  1682 		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1683 
  1684 	RecordFormatBuf().iChannels = 2;
  1685 
  1686 	// Find first supported rate and set the the audio configuration to use it
  1687 	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
  1688 		{
  1689 		// check record channel
  1690 		RecordFormatBuf().iRate = (TSoundRate)i;
  1691 		if (RecordCapsBuf().iRates & (1 << i))
  1692 			{
  1693 			// Caps reports it is supported
  1694 			r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
  1695 			CHECK_NOERROR(r);
  1696 			break;
  1697 			}
  1698 		}
  1699 	// Check we found/set a valid format
  1700 	CHECK(i <= ESoundRate48000Hz);
  1701 
  1702 	// Set recording format
  1703 	PrintConfig(RecordFormatBuf(),Test);
  1704 
  1705 	// Set the volume level
  1706 	RxSoundDevice.SetVolume(KSoundMaxVolume);
  1707 
  1708 	// Set the record buffer configuration, then read it back.
  1709 	RChunk chunk;
  1710 	TInt bufSize = 64 * 1024; // The defect is seen, on windows, when the buffer size is 64k and the LDD does 2x 32k transfers per buffer
  1711 	TTestSharedChunkBufConfig bufferConfig;
  1712 	bufferConfig.iNumBuffers=7;		
  1713 	bufferConfig.iBufferSizeInBytes=bufSize;
  1714 	bufferConfig.iFlags=0;
  1715 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
  1716 	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
  1717 	CHECK_NOERROR(r);
  1718 	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
  1719 	PrintBufferConf(bufferConfig,Test);
  1720 	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
  1721 
  1722 	// Calculate time required to fill a single 64k byte buffer
  1723  	TUint32 durationOneBufferMsec = (1000 * bufSize) / BytesPerSecond(RecordFormatBuf());
  1724     Test.Printf(_L("durationOneBufferMsec %d\n"), durationOneBufferMsec);
  1725 
  1726 	// Start recording....
  1727     Test.Printf(_L("Issue 3 RecordData requests then wait to pause during second internal 32k internal transfers of the second buffer...\n"));
  1728 	for(i=0; i<3; ++i)
  1729 		{
  1730 	    RxSoundDevice.RecordData(status[i], length[i]);
  1731 		}
  1732     
  1733 	// Wait for 1 3/4 64k buffers. In  other words, wait for 3.75x32k byte internal transfers so we pause during the second transfer of the second buffer
  1734  	User::After(durationOneBufferMsec *1000 * (1 + 3/4) );
  1735 
  1736     CHECK_NOERROR(RxSoundDevice.Pause());
  1737     Test.Printf(_L("Paused\n"));
  1738 
  1739 	for(i=0; i<3; ++i)
  1740 		{
  1741 		User::WaitForRequest(status[i]);
  1742 		Test.Printf(_L("status[%d].Int() = %d\n"), i, status[i].Int());
  1743 		Test.Printf(_L("length[%d] = %d\n"), i, length[i]);
  1744 		}
  1745 
  1746 	bool testValid = true;
  1747 
  1748 	if((status[0].Int() < 0) || (length[0] != bufSize))
  1749 		{
  1750 		testValid = false;
  1751 		Test.Printf(_L("Test invalid because pause hit first request\n"));
  1752 		}
  1753 
  1754 	if(testValid && (status[1].Int() == KErrCancel))
  1755 		{
  1756 		testValid = false;
  1757 		Test.Printf(_L("Test invalid because pause hit before second request started\n"));
  1758 		}
  1759 
  1760 	if(testValid && (status[2].Int() != KErrCancel))
  1761 		{
  1762 		testValid = false;
  1763 		Test.Printf(_L("Test invalid because pause missed all requests\n"));
  1764 		}
  1765 
  1766 	if(testValid)
  1767 		{
  1768 		Test.Printf(_L("Appear to have issued pause at the correct time, check results\n"));
  1769 		// First request should have completed with a full buffer of data
  1770 		CHECK(status[0].Int() >= 0);
  1771     	CHECK(length[0] == bufSize);
  1772 
  1773 		// second request should have been truncated
  1774 		CHECK(status[1].Int() >= 0);
  1775    		CHECK(length[1] < bufSize);
  1776 
  1777 		// Last request should have been cancelled.
  1778 		CHECK(status[2].Int() == KErrCancel);
  1779 		}
  1780 	Test.Printf(_L("DTW-MM00678 test done\r\n"));
  1781 
  1782     //CHECK_NOERROR(RxSoundDevice.Resume());
  1783 	
  1784     // Make sure recording is not in progress
  1785 	RxSoundDevice.CancelRecordData();
  1786 	TxSoundDevice.CancelPlayData();
  1787 	
  1788 	chunk.Close();
  1789 	return;
  1790 	}
  1791 #endif
  1792 
  1793 LOCAL_C void TestUnloadDrivers()
  1794 	{
  1795 	TInt r=User::FreeLogicalDevice(KDevSoundScName);
  1796 	Test.Printf(_L("Unloading %S.LDD - %d\r\n"),&KDevSoundScName,r);
  1797 	CHECK_NOERROR(r);
  1798 
  1799 	TName pddName(KDevSoundScName);
  1800 	_LIT(KPddWildcardExtension,".*");
  1801 	pddName.Append(KPddWildcardExtension);
  1802 	TFindPhysicalDevice findPD(pddName);
  1803 	TFullName findResult;
  1804 	r=findPD.Next(findResult);
  1805 	while (r==KErrNone)
  1806 		{
  1807 		r=User::FreePhysicalDevice(findResult);
  1808 		Test.Printf(_L("Unloading %S.PDD - %d\r\n"),&findResult,r);
  1809 		CHECK_NOERROR(r);
  1810 		findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container.
  1811 		r=findPD.Next(findResult);
  1812 		}
  1813 	}
  1814 
  1815 void TestTimePlayed()
  1816 	{
  1817 	TTimeIntervalMicroSecondsBuf timeIntervalBuf;
  1818 
  1819 	// Don't try to do the tests if TimePlayed() is not supported
  1820 	TInt r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  1821 	if (r == KErrNotSupported)
  1822 		{
  1823 		Test.Printf(_L("TimePlayed() is not supported, skipping tests\n"));
  1824 		return;
  1825 		}
  1826 	CHECK_NOERROR(r);
  1827 
  1828 	TInt rate;
  1829 
  1830 	// Find first supported rate and set the the audio configuration to use it
  1831 	for (rate = 0; rate <= ESoundRate48000Hz; ++rate)
  1832 		{
  1833 		if (PlayCapsBuf().iRates & (1 << rate))
  1834 			{
  1835 			break;
  1836 			}
  1837 		}
  1838 
  1839 	// Test mono and Stereo
  1840 	for (TInt channels=1; channels<=2; ++channels)
  1841 	{
  1842 		TRequestStatus stat[2];
  1843 
  1844 		Test.Next(_L("Preparing to play..."));
  1845 		if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
  1846 			PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  1847 		PlayFormatBuf().iRate = (TSoundRate) rate;
  1848 		PlayFormatBuf().iChannels = channels;
  1849 		PrintConfig(PlayFormatBuf(),Test);
  1850 		r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
  1851 		CHECK_NOERROR(r);
  1852 
  1853 		// Set the play buffer configuration, then read it back.
  1854 		RChunk chunk;
  1855 		TInt bufSize=BytesPerSecond(PlayFormatBuf()); 									// Large enough to hold 1 second of data.
  1856 		bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
  1857 		TTestSharedChunkBufConfig bufferConfig;
  1858 		bufferConfig.iNumBuffers=2;
  1859 		bufferConfig.iBufferSizeInBytes=bufSize;
  1860 		bufferConfig.iFlags=0;		// All buffers will be contiguous
  1861 		TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
  1862 		r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
  1863 		CHECK_NOERROR(r);
  1864 		TxSoundDevice.GetBufferConfig(bufferConfigBuf);
  1865 		PrintBufferConf(bufferConfig,Test);
  1866 		CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
  1867 		TPtr8* tPtr[2];
  1868 		TInt i;
  1869 		for (i=0;i<2;i++)
  1870 			tPtr[i]=new TPtr8(chunk.Base()+bufferConfig.iBufferOffsetList[i],bufSize);
  1871 
  1872 
  1873 		r=MakeSineTable(PlayFormatBuf());
  1874 		CHECK_NOERROR(r);
  1875 		r=SetToneFrequency(440,PlayFormatBuf());
  1876 		CHECK_NOERROR(r);
  1877 
  1878 		WriteTone(*tPtr[0],PlayFormatBuf());
  1879 		WriteTone(*tPtr[1],PlayFormatBuf());
  1880 
  1881 		// set up a timer to interrogate time played
  1882 		TRequestStatus timerStat;
  1883 		RTimer timer;
  1884 		timer.CreateLocal();
  1885 		TTimeIntervalMicroSeconds32 timerInterval(50000);
  1886 
  1887 		TInt64 currentTime, previousTime;
  1888 
  1889 		Test.Next(_L("Time Played..."));
  1890 
  1891 		currentTime = previousTime = MAKE_TINT64(0,0);
  1892 
  1893 		TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,0);
  1894 		TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],bufSize,KSndFlagLastSample);
  1895 
  1896 		// check requests are pending
  1897 		CHECK_EQUAL(stat[0].Int(),KRequestPending);
  1898 		CHECK_EQUAL(stat[1].Int(),KRequestPending);
  1899 
  1900 		// check time recorded is not supported for play channel
  1901 		CHECK(TxSoundDevice.TimeRecorded(timeIntervalBuf)==KErrNotSupported);
  1902 
  1903 		timer.After(timerStat,timerInterval);
  1904 		// first buffer
  1905 		while (stat[0] == KRequestPending)
  1906 			{
  1907 			User::WaitForRequest(stat[0],timerStat);
  1908 			Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  1909 			previousTime = currentTime;
  1910 			r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  1911 			CHECK_NOERROR(r);
  1912 			currentTime = timeIntervalBuf().Int64();
  1913 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  1914 
  1915 			// ensure time is increasing or function is not supported
  1916 			CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  1917 
  1918 			if (timerStat != KRequestPending)
  1919 				{
  1920 				timer.After(timerStat,timerInterval);
  1921 				}
  1922 			}
  1923 		timer.Cancel();
  1924 
  1925 		Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  1926 		r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  1927 		CHECK_NOERROR(r);
  1928 		currentTime = timeIntervalBuf().Int64();
  1929 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  1930 
  1931 		CHECK_EQUAL(stat[0].Int(),KErrNone);
  1932 
  1933 		timer.After(timerStat,timerInterval);
  1934 		// second buffer
  1935 		while (stat[1] == KRequestPending)
  1936 			{
  1937 			User::WaitForRequest(stat[1],timerStat);
  1938 			Test.Printf(_L("stat[1] %x, timerStat %x\n"),stat[1].Int(),timerStat.Int());
  1939 			previousTime = currentTime;
  1940 			r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  1941 			CHECK_NOERROR(r);
  1942 
  1943 			currentTime = timeIntervalBuf().Int64();
  1944 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  1945 
  1946 			// ensure time is increasing or function is not supported
  1947 			if (stat[1] == KRequestPending) // still playing
  1948 				{
  1949 				CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  1950 				}
  1951 
  1952 			if (timerStat != KRequestPending)
  1953 				{
  1954 				timer.After(timerStat,timerInterval);
  1955 				}
  1956 
  1957 			}
  1958 		timer.Cancel();
  1959 
  1960 		Test.Printf(_L("stat[1] %x, timerStat %x\n"),stat[1].Int(),timerStat.Int());
  1961 		r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  1962 		CHECK_NOERROR(r);
  1963 
  1964 		currentTime = timeIntervalBuf().Int64();
  1965 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(timeIntervalBuf().Int64()),I64LOW(timeIntervalBuf().Int64()));
  1966 
  1967 		CHECK_EQUAL(stat[1].Int(),KErrNone);
  1968 
  1969 		//
  1970 		// Time Played with pause
  1971 		//
  1972 
  1973 		Test.Next(_L("Time Played with pause..."));
  1974 
  1975 		TTimeIntervalMicroSeconds32 pauseInterval(2000000);
  1976 		TBool paused = EFalse;
  1977 
  1978 		currentTime = previousTime = MAKE_TINT64(0,0);
  1979 		timer.Cancel();
  1980 
  1981 		TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,0);
  1982 		TxSoundDevice.PlayData(stat[1],bufferConfig.iBufferOffsetList[1],bufSize,KSndFlagLastSample);
  1983 
  1984 		// check requests are pending
  1985 		CHECK_EQUAL(stat[0].Int(),KRequestPending);
  1986 		CHECK_EQUAL(stat[1].Int(),KRequestPending);
  1987 
  1988 		// check time recorded is not supported for play channel
  1989 		CHECK(TxSoundDevice.TimeRecorded(timeIntervalBuf)==KErrNotSupported);
  1990 
  1991 		timer.After(timerStat,timerInterval);
  1992 		// first buffer
  1993 		while (stat[0] == KRequestPending)
  1994 			{
  1995 			User::WaitForRequest(stat[0],timerStat);
  1996 			Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  1997 			previousTime = currentTime;
  1998 			r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  1999 			CHECK_NOERROR(r);
  2000 			currentTime = timeIntervalBuf().Int64();
  2001 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2002 
  2003 			// ensure time is increasing or function is not supported
  2004 			CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  2005 
  2006 			// Pause and resume ...
  2007 			if (paused == EFalse && I64LOW(currentTime) > 500000)
  2008 				{
  2009 				paused = ETrue;
  2010 				TxSoundDevice.Pause();
  2011 				r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  2012 				CHECK_NOERROR(r);
  2013 				TInt64 pausedTime1 = timeIntervalBuf().Int64();
  2014 				Test.Printf(_L("Paused time_high %d, time_low %d\n"),I64HIGH(pausedTime1),I64LOW(pausedTime1));
  2015 
  2016 				User::After(pauseInterval);
  2017 
  2018 				r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  2019 				CHECK_NOERROR(r);
  2020 				TInt64 pausedTime2 = timeIntervalBuf().Int64();
  2021 				Test.Printf(_L("Resumed time_high %d, time_low %d\n"),I64HIGH(pausedTime2),I64LOW(pausedTime2));
  2022 				//CHECK(pausedTime1 == pausedTime2);
  2023 				TxSoundDevice.Resume();
  2024 				}
  2025 
  2026 			if (timerStat != KRequestPending)
  2027 				{
  2028 				timer.After(timerStat,timerInterval);
  2029 				}
  2030 			}
  2031 		timer.Cancel();
  2032 
  2033 		Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  2034 		r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  2035 		CHECK_NOERROR(r);
  2036 		currentTime = timeIntervalBuf().Int64();
  2037 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2038 
  2039 		CHECK_EQUAL(stat[0].Int(),KErrNone);
  2040 
  2041 		timer.After(timerStat,timerInterval);
  2042 		// second buffer
  2043 		while (stat[1] == KRequestPending)
  2044 			{
  2045 			User::WaitForRequest(stat[1],timerStat);
  2046 			Test.Printf(_L("stat[1] %x, timerStat %x\n"),stat[1].Int(),timerStat.Int());
  2047 			previousTime = currentTime;
  2048 			r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  2049 			CHECK_NOERROR(r);
  2050 
  2051 			currentTime = timeIntervalBuf().Int64();
  2052 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2053 
  2054 			// ensure time is increasing or function is not supported
  2055 			if (stat[1] == KRequestPending) // still playing
  2056 				{
  2057 				CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  2058 				}
  2059 
  2060 			if (timerStat != KRequestPending)
  2061 				{
  2062 				timer.After(timerStat,timerInterval);
  2063 				}
  2064 
  2065 			}
  2066 		timer.Cancel();
  2067 
  2068 		Test.Printf(_L("stat[1] %x, timerStat %x\n"),stat[1].Int(),timerStat.Int());
  2069 		r = TxSoundDevice.TimePlayed(timeIntervalBuf);
  2070 		CHECK_NOERROR(r);
  2071 
  2072 		currentTime = timeIntervalBuf().Int64();
  2073 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(timeIntervalBuf().Int64()),I64LOW(timeIntervalBuf().Int64()));
  2074 
  2075 		CHECK_EQUAL(stat[1].Int(),KErrNone);
  2076 
  2077 		// clean up
  2078 		timer.Close();
  2079 		chunk.Close();
  2080 		for (i=0;i<2;i++)
  2081 			delete tPtr[i];
  2082 
  2083 		} // channel loop
  2084 	}
  2085 
  2086 void TestTimeRecorded()
  2087 	{
  2088 	TTimeIntervalMicroSecondsBuf timeIntervalBuf;
  2089 
  2090 	TInt r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2091 	if (r == KErrNotSupported)
  2092 		{
  2093 		Test.Printf(_L("TimeRecorded() is not supported, skipping tests\n"));
  2094 		return;
  2095 		}
  2096 	CHECK_NOERROR(r);
  2097 
  2098 	TInt rate;
  2099 
  2100 	// Find first supported rate and set the the audio configuration to use it
  2101 	for (rate = 0; rate <= ESoundRate48000Hz; ++rate)
  2102 		{
  2103 		if (PlayCapsBuf().iRates & (1 << rate))
  2104 			{
  2105 			break;
  2106 			}
  2107 		}
  2108 
  2109 	// Test mono and Stereo
  2110 	for (TInt channels=1; channels<=2; ++channels)
  2111 	{
  2112 		TRequestStatus stat[2];
  2113 
  2114 		Test.Next(_L("Preparing to record..."));
  2115 		if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
  2116 			RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
  2117 		RecordFormatBuf().iRate = (TSoundRate) rate;
  2118 		RecordFormatBuf().iChannels = channels;
  2119 		PrintConfig(RecordFormatBuf(),Test);
  2120 		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
  2121 		CHECK_NOERROR(r);
  2122 
  2123 		// Set the play buffer configuration, then read it back.
  2124 		RChunk chunk;
  2125 		TInt bufSize=BytesPerSecond(RecordFormatBuf()); 									// Large enough to hold 1 second of data.
  2126 		bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());		// Keep the buffer length valid for driver.
  2127 		TTestSharedChunkBufConfig bufferConfig;
  2128 		bufferConfig.iNumBuffers=4;
  2129 		bufferConfig.iBufferSizeInBytes=bufSize;
  2130 		bufferConfig.iFlags=0;		// All buffers will be contiguous
  2131 		TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
  2132 		r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
  2133 		CHECK_NOERROR(r);
  2134 		RxSoundDevice.GetBufferConfig(bufferConfigBuf);
  2135 		PrintBufferConf(bufferConfig,Test);
  2136 		CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
  2137 
  2138 		// set up a timer to interrogate time played
  2139 		TRequestStatus timerStat;
  2140 		RTimer timer;
  2141 		timer.CreateLocal();
  2142 		TTimeIntervalMicroSeconds32 timerInterval(50000);
  2143 
  2144 		TInt64 currentTime, previousTime;
  2145 
  2146 		Test.Next(_L("Time Recorded..."));
  2147 
  2148 		currentTime = previousTime = MAKE_TINT64(0,0);
  2149 
  2150 		TInt length1=0, length2=0;
  2151 		RxSoundDevice.RecordData(stat[0],length1);
  2152 		RxSoundDevice.RecordData(stat[1],length2);
  2153 
  2154 		// check requests are pending
  2155 		CHECK_EQUAL(stat[0].Int(),KRequestPending);
  2156 		CHECK_EQUAL(stat[1].Int(),KRequestPending);
  2157 
  2158 		// check time played is not supported for record channel
  2159 		CHECK(RxSoundDevice.TimePlayed(timeIntervalBuf)==KErrNotSupported);
  2160 
  2161 		timer.After(timerStat,timerInterval);
  2162 		// first buffer
  2163 		while (stat[0] == KRequestPending)
  2164 			{
  2165 			User::WaitForRequest(stat[0],timerStat);
  2166 			Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  2167 			previousTime = currentTime;
  2168 			r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2169 			CHECK_NOERROR(r);
  2170 			currentTime = timeIntervalBuf().Int64();
  2171 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2172 
  2173 			// ensure time is increasing or function is not supported
  2174 			CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  2175 
  2176 			if (timerStat != KRequestPending)
  2177 				{
  2178 				timer.After(timerStat,timerInterval);
  2179 				}
  2180 			}
  2181 		timer.Cancel();
  2182 
  2183 		Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  2184 		r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2185 		CHECK_NOERROR(r);
  2186 		currentTime = timeIntervalBuf().Int64();
  2187 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2188 
  2189 		CHECK(stat[0].Int() == 0);
  2190 
  2191 		timer.After(timerStat,timerInterval);
  2192 		// second buffer
  2193 		while (stat[1] == KRequestPending)
  2194 			{
  2195 			User::WaitForRequest(stat[1],timerStat);
  2196 			Test.Printf(_L("stat[1] %x, timerStat %x\n"),stat[1].Int(),timerStat.Int());
  2197 			previousTime = currentTime;
  2198 			r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2199 			CHECK_NOERROR(r);
  2200 			currentTime = timeIntervalBuf().Int64();
  2201 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2202 
  2203 			// ensure time is increasing or function is not supported
  2204 			if (stat[1] == KRequestPending) // still playing
  2205 				{
  2206 				CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  2207 				}
  2208 
  2209 			if (timerStat != KRequestPending)
  2210 				{
  2211 				timer.After(timerStat,timerInterval);
  2212 				}
  2213 
  2214 			}
  2215 		timer.Cancel();
  2216 
  2217 		Test.Printf(_L("stat[1] %x, timerStat %x\n"),stat[1].Int(),timerStat.Int());
  2218 		r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2219 		CHECK_NOERROR(r);
  2220 		currentTime = timeIntervalBuf().Int64();
  2221 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(timeIntervalBuf().Int64()),I64LOW(timeIntervalBuf().Int64()));
  2222 
  2223 		CHECK(stat[1].Int() > 0);
  2224 
  2225 		// stop recording into the next buffer
  2226 		RxSoundDevice.CancelRecordData();
  2227 
  2228 		// Release the buffers
  2229 		r = RxSoundDevice.ReleaseBuffer(stat[0].Int());
  2230 		CHECK_EQUAL(r, KErrNone);
  2231 		r = RxSoundDevice.ReleaseBuffer(stat[1].Int());
  2232 		CHECK_EQUAL(r, KErrNone);
  2233 
  2234 		//
  2235 		// Time Recorded with pause
  2236 		//
  2237 
  2238 		Test.Next(_L("Time Recorded with pause..."));
  2239 
  2240 		TTimeIntervalMicroSeconds32 pauseInterval(2000000);
  2241 		TBool paused = EFalse;
  2242 
  2243 		currentTime = previousTime = MAKE_TINT64(0,0);
  2244 
  2245 	    // Record and discard some data to make sure all testing is not within the first buffer...
  2246 		RxSoundDevice.RecordData(stat[0],length1);
  2247         User::WaitForRequest(stat[0]);
  2248         CHECK(stat[0].Int() >= 0);
  2249         RxSoundDevice.ReleaseBuffer(stat[0].Int());
  2250         
  2251 		RxSoundDevice.RecordData(stat[0],length1);
  2252         RxSoundDevice.RecordData(stat[1],length2);
  2253 		
  2254 		// check requests are pending
  2255 		CHECK_EQUAL(stat[0].Int(),KRequestPending);
  2256 
  2257 		// check time recorded is not supported for play channel
  2258 		CHECK(RxSoundDevice.TimePlayed(timeIntervalBuf)==KErrNotSupported);
  2259 
  2260 		timer.After(timerStat,timerInterval);
  2261 		// first buffer
  2262 		while (stat[0] == KRequestPending)
  2263 			{
  2264 			User::WaitForRequest(stat[0],timerStat);
  2265 			Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  2266 			previousTime = currentTime;
  2267 			r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2268 			CHECK_NOERROR(r);
  2269 			currentTime = timeIntervalBuf().Int64();
  2270 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2271 
  2272 			// ensure time is increasing or function is not supported
  2273 			CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  2274 
  2275 			// Pause and resume ...
  2276 			if (paused == EFalse && I64LOW(currentTime) > 500000)
  2277 				{
  2278 				paused = ETrue;
  2279 				RxSoundDevice.Pause();
  2280 				r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2281 				CHECK_NOERROR(r);
  2282 				TInt64 pausedTime1 = timeIntervalBuf().Int64();
  2283 				Test.Printf(_L("Paused time_high %d, time_low %d\n"),I64HIGH(pausedTime1),I64LOW(pausedTime1));
  2284 	            // Check time is increasing
  2285 	            CHECK((I64LOW(pausedTime1) >= I64LOW(currentTime)));
  2286 
  2287 				User::After(pauseInterval);
  2288 
  2289 				r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2290 				CHECK_NOERROR(r);
  2291 				TInt64 pausedTime2 = timeIntervalBuf().Int64();
  2292 				Test.Printf(_L("Resumed time_high %d, time_low %d\n"),I64HIGH(pausedTime2),I64LOW(pausedTime2));
  2293                 // Check time is unchanged
  2294                 CHECK((I64LOW(pausedTime2) == I64LOW(pausedTime1)));
  2295 				}
  2296 
  2297 			if (timerStat != KRequestPending)
  2298 				{
  2299 				timer.After(timerStat,timerInterval);
  2300 				}
  2301 			}
  2302 
  2303 		timer.Cancel();
  2304 
  2305 		// Buffer should complete normally or be empty (indicated by KErrCancel)
  2306 		CHECK((stat[0].Int() >= 0) || (stat[0].Int() == KErrCancel));
  2307 		// Release the first buffer, if it contained any data
  2308 		if (stat[0].Int() >= 0)
  2309 			{
  2310 			r = RxSoundDevice.ReleaseBuffer(stat[0].Int());
  2311 			CHECK_EQUAL(r, KErrNone);
  2312 			}
  2313 		// Check second buffer completed or cancelled
  2314 		User::WaitForRequest(stat[1]);
  2315 		CHECK_EQUAL(stat[1].Int(), KErrCancel);
  2316 
  2317 		// Now resume the recording
  2318 		r = RxSoundDevice.Resume();
  2319 		CHECK_EQUAL(r, KErrNone);
  2320 
  2321 		// Need to re-setup buffers
  2322 		RxSoundDevice.RecordData(stat[0],length1);
  2323 		RxSoundDevice.RecordData(stat[1],length2);
  2324 
  2325 		timer.After(timerStat,timerInterval);
  2326 		// another buffer
  2327 		while (stat[0] == KRequestPending)
  2328 			{
  2329 			User::WaitForRequest(stat[0],timerStat);
  2330 			Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  2331 			previousTime = currentTime;
  2332 			r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2333 			CHECK_NOERROR(r);
  2334 			currentTime = timeIntervalBuf().Int64();
  2335 			Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(currentTime),I64LOW(currentTime));
  2336 
  2337 			// ensure time is increasing or function is not supported
  2338 			if (stat[0] == KRequestPending) // still recording
  2339 				{
  2340 				CHECK((I64LOW(currentTime) >= I64LOW(previousTime)) || r == KErrNotSupported);
  2341 				}
  2342 
  2343 			if (timerStat != KRequestPending)
  2344 				{
  2345 				timer.After(timerStat,timerInterval);
  2346 				}
  2347 
  2348 			}
  2349 		timer.Cancel();
  2350 
  2351 		Test.Printf(_L("stat[0] %x, timerStat %x\n"),stat[0].Int(),timerStat.Int());
  2352 		r = RxSoundDevice.TimeRecorded(timeIntervalBuf);
  2353 		CHECK_NOERROR(r);
  2354 		currentTime = timeIntervalBuf().Int64();
  2355 		Test.Printf(_L("time_high %d, time_low %d\n"),I64HIGH(timeIntervalBuf().Int64()),I64LOW(timeIntervalBuf().Int64()));
  2356 
  2357 		CHECK(stat[0].Int() > 0);
  2358 
  2359 		// stop recording into the next buffer
  2360 		RxSoundDevice.CancelRecordData();
  2361 
  2362 		// Release the buffers
  2363 		r = RxSoundDevice.ReleaseBuffer(stat[0].Int());
  2364 		CHECK_EQUAL(r, KErrNone);
  2365 
  2366 		// clean up
  2367 		timer.Close();
  2368 		chunk.Close();
  2369 		} // channel loop
  2370 	}
  2371 
  2372 TInt E32Main()
  2373 	{
  2374 //	User::SetDebugMask(0x10,1); // Enable KSOUND1
  2375 
  2376 	__UHEAP_MARK;
  2377 	TInt r;
  2378 
  2379 	Test.Title();
  2380 
  2381 	Test.Start(_L("Load"));
  2382 	if (Load()==KErrNotFound)
  2383 		{
  2384 		Test.Printf(_L("Shared chunk sound driver not supported - test skipped\r\n"));
  2385 		Test.End();
  2386 		Test.Close();
  2387 		__UHEAP_MARKEND;
  2388 		return(KErrNone);
  2389 		}
  2390 
  2391 	__KHEAP_MARK;
  2392 
  2393 	/**	@SYMTestCaseID 		PBASE-T_SOUND2-223
  2394 	@SYMTestCaseDesc 		Opening the channel - normal
  2395 	@SYMTestPriority 		Critical
  2396 	@SYMTestActions			1)	With the LDD and PDD installed and with all channels closed on the device,
  2397 								open a channel for playback on the device.
  2398 							2)	Without closing the playback channel, open a channel for record on the device.
  2399 							3)	Close the playback channel and then open it again.
  2400 							4)	Close the record channel and then open it again.
  2401 	@SYMTestExpectedResults	1)	KErrNone - Channel opens successfully.
  2402 							2)	KErrNone - Channel opens successfully.
  2403 							3)	KErrNone - Channel re-opens successfully.
  2404 							4)	KErrNone - Channel re-opens successfully.
  2405 	@SYMREQ					PREQ1073.4 */
  2406 
  2407 	Test.Next(_L("Open playback channel"));
  2408 	r = TxSoundDevice.Open(KSoundScTxUnit0);
  2409 	CHECK_NOERROR(r);
  2410 
  2411 	Test.Next(_L("Open record channel"));
  2412 	r = RxSoundDevice.Open(KSoundScRxUnit0);
  2413 	CHECK_NOERROR(r);
  2414 
  2415 	Test.Next(_L("Query play formats supported"));
  2416 	TxSoundDevice.Caps(PlayCapsBuf);
  2417 	TSoundFormatsSupportedV02 playCaps=PlayCapsBuf();
  2418 	PrintCaps(playCaps,Test);
  2419 
  2420 	Test.Next(_L("Close playback channel"));
  2421 	TxSoundDevice.Close();
  2422 	Test.Next(_L("Re-open playback channel"));
  2423 	r = TxSoundDevice.Open(KSoundScTxUnit0);
  2424 	CHECK_NOERROR(r);
  2425 	Test.Next(_L("Close record channel"));
  2426 	RxSoundDevice.Close();
  2427 	Test.Next(_L("Re-open record channel"));
  2428 	r = RxSoundDevice.Open(KSoundScRxUnit0);
  2429 	CHECK_NOERROR(r);
  2430 
  2431 	Test.Next(_L("Query play formats supported"));
  2432 	TxSoundDevice.Caps(PlayCapsBuf);
  2433 	PrintCaps(playCaps,Test);
  2434 
  2435 	Test.Next(_L("Query record formats supported"));
  2436 	RxSoundDevice.Caps(RecordCapsBuf);
  2437 	TSoundFormatsSupportedV02 recordCaps=RecordCapsBuf();
  2438 	PrintCaps(recordCaps,Test);
  2439 
  2440 	Test.Next(_L("Query current play settings"));
  2441 	TxSoundDevice.AudioFormat(PlayFormatBuf);
  2442 	TCurrentSoundFormatV02 playFormat=PlayFormatBuf();
  2443 	PrintConfig(playFormat,Test);
  2444 	CheckConfig(playFormat,playCaps);
  2445 
  2446 	Test.Next(_L("Query current record settings"));
  2447 	RxSoundDevice.AudioFormat(RecordFormatBuf);
  2448 	TCurrentSoundFormatV02 recordFormat=RecordFormatBuf();
  2449 	PrintConfig(recordFormat,Test);
  2450 	CheckConfig(recordFormat,recordCaps);
  2451 
  2452 	Test.Next(_L("Set play format"));
  2453 	if (playCaps.iEncodings&KSoundEncoding16BitPCM)
  2454 		playFormat.iEncoding = ESoundEncoding16BitPCM;
  2455 	PrintConfig(playFormat,Test);
  2456 	r = TxSoundDevice.SetAudioFormat(PlayFormatBuf);
  2457 	CHECK_NOERROR(r);
  2458 
  2459 	Test.Next(_L("Set Record Format"));
  2460 	if (recordCaps.iEncodings&KSoundEncoding16BitPCM)
  2461 		recordFormat.iEncoding = ESoundEncoding16BitPCM;
  2462 	PrintConfig(recordFormat,Test);
  2463 	r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
  2464 	CHECK_NOERROR(r);
  2465 
  2466 #ifdef SOAKTEST
  2467 	TInt freeRamInBytes=0;
  2468 	TTime stim;
  2469 	stim.HomeTime();
  2470 
  2471 	FOREVER
  2472 		{
  2473 #endif
  2474 
  2475 		TestBasicPlayFunctions();
  2476 		TestBasicRecordFunctions();
  2477 		TestPlayAllRates(1,4);
  2478 		TestPlayAllRates(2,4);
  2479 		TestRecordAllRates(1,4);
  2480 		TestRecordAllRates(2,4);
  2481 		TestRecordVolume(2,10);
  2482 		TestPlayCancel();
  2483 		TestRecordCancel();
  2484 		TestRecordPauseResume(1);
  2485 		TestRecordPauseResume(2);
  2486 		TestSimultaneousPlayRecord();
  2487 		TestTimePlayed();
  2488 		TestTimeRecorded();
  2489 #ifdef __WINS__
  2490 		TestDefectDTWMM00678();
  2491 #endif
  2492         //TestSpeed(); // Gives information which may help debug h4 FMM issues
  2493 
  2494 #ifdef SOAKTEST
  2495 		TInt free;
  2496 		HAL::Get(HAL::EMemoryRAMFree,free);
  2497 	Test.Printf(_L("Free ram is %d bytes\r\n"),free);
  2498 //	if (freeRamInBytes)
  2499 //		CHECK(freeRamInBytes == free)
  2500 	freeRamInBytes=free;
  2501 
  2502 	TTime ntim;
  2503 		ntim.HomeTime();
  2504 		TTimeIntervalMinutes elapsed;
  2505 		r=ntim.MinutesFrom(stim,elapsed);
  2506 		CHECK_NOERROR(r);
  2507 		Test.Printf(_L("Test has been running for %d minutes\r\n"),elapsed.Int());
  2508 		}
  2509 #endif
  2510 
  2511 	Test.Next(_L("Close channels"));
  2512 	RxSoundDevice.Close();
  2513 	TxSoundDevice.Close();
  2514 
  2515 	__KHEAP_MARKEND;
  2516 
  2517 	// Now that both the channels are closed, unload the LDD and the PDDs.
  2518 	TestUnloadDrivers();
  2519 
  2520 	Test.End();
  2521 	Test.Close();
  2522 
  2523 	Cleanup();
  2524 	__UHEAP_MARKEND;
  2525 	User::Allocator().Check();
  2526 	return(KErrNone);
  2527 	}