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