kerneltest/e32test/multimedia/t_sound_api.cpp
changeset 0 a41df078684a
child 15 4122176ea935
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/multimedia/t_sound_api.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1372 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\multimedia\t_sound_api.cpp
+// 
+//
+
+/**
+ @file Shared chunk sound driver API test code.
+*/
+
+#include <e32test.h>
+#include <f32file.h>
+#include "t_soundutils.h"
+
+#define CHECK(aValue) {Test(aValue);}
+#define CHECK_NOERROR(aValue) { TInt v=(aValue); if(v) { Test.Printf(_L("Error value = %d\n"),v); Test(EFalse,__LINE__); }}
+#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__); }}
+
+_LIT(KSndLddFileName,"ESOUNDSC.LDD");
+_LIT(KSndPddFileName,"SOUNDSC.PDD");
+
+RTest Test(_L("T_SOUND_API"));
+RSoundSc TxSoundDevice;
+RSoundSc RxSoundDevice;
+
+TSoundFormatsSupportedV02Buf RecordCapsBuf;
+TSoundFormatsSupportedV02Buf PlayCapsBuf;
+TCurrentSoundFormatV02Buf PlayFormatBuf;
+TCurrentSoundFormatV02Buf RecordFormatBuf;
+
+LOCAL_C TInt Load()
+	{
+	TInt r;
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-219
+	@SYMTestCaseDesc 		Installing the PDD
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	Attempt to install the PDD (using User::LoadPhysicalDevice()). 
+							2)	Without un-installing it, attempt to install it a second time.
+	@SYMTestExpectedResults	1)	KErrNone - PDD loads successfully. 
+							2)	Should fail with KErrAlreadyExists.
+	@SYMREQ					PREQ1073.4 */
+
+	Test.Start(_L("Load sound PDD"));
+	r=User::LoadPhysicalDevice(KSndPddFileName);
+	if (r==KErrNotFound)
+		{
+		Test.End();
+		return(r);
+		}
+	CHECK(r==KErrNone || r==KErrAlreadyExists);
+	r=User::LoadPhysicalDevice(KSndPddFileName);
+	CHECK(r==KErrAlreadyExists);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-220
+	@SYMTestCaseDesc 		Installing the LDD
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	Attempt to install the LDD (using User::LoadLogicalDevice()). 
+							2)	Without un-installing it, attempt to install it a second time.
+	@SYMTestExpectedResults	1)	KErrNone - LDD loads successfully. 
+							2)	Should fail with KErrAlreadyExists.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Load sound LDD"));
+	r=User::LoadLogicalDevice(KSndLddFileName);
+	CHECK(r==KErrNone || r==KErrAlreadyExists);
+	r=User::LoadPhysicalDevice(KSndPddFileName);
+	CHECK(r==KErrAlreadyExists);
+
+	Test.End();
+	return(KErrNone);
+	}
+
+LOCAL_C void TestSetAudioFormat()
+	{
+	TInt r;
+	Test.Printf(_L("Testing setting the audio format\r\n"));
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-227
+	@SYMTestCaseDesc 		Setting the audio configuration - channel configuration.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Read the audio capabilities of the playback channel. For each of the possible 6 channel 
+							configurations, issue a request on the playback channel to set this audio configuration.
+	@SYMTestExpectedResults	Either KErrNone if the playback channel supports the channel configuration, or
+							KErrNotSupported if the playback channel does not support the channel configuration. 
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Try to set every possible audio channel configuration"));
+	TxSoundDevice.AudioFormat(PlayFormatBuf);	// Read back the current setting which must be valid.
+	TInt i;
+	for (i=0 ; i < 6 ; i++)
+		{
+		PlayFormatBuf().iChannels = (i+1);
+		r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+		if (PlayCapsBuf().iChannels & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			}					
+		else
+			{
+			CHECK(r==KErrNotSupported);		// Caps reports it is not supported
+			}		
+		}
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-228
+	@SYMTestCaseDesc 		Setting the audio configuration - sample rate.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Read the audio capabilities of the playback channel. For each of the possible 14 sample 
+							rates, issue a request on the playback channel to set this audio configuration.
+	@SYMTestExpectedResults	Either KErrNone if the playback channel supports the sample rate, or
+							KErrNotSupported if the playback channel does not support the sample rate. 
+	@SYMREQ					PREQ1073.4 */
+		
+	Test.Next(_L("Try to set every possible sample rate"));
+	TxSoundDevice.AudioFormat(PlayFormatBuf);	// Read back the current setting which must be valid.
+	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
+		{
+		PlayFormatBuf().iRate = (TSoundRate)i;
+		r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+		if (PlayCapsBuf().iRates & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			}					
+		else
+			{
+			CHECK(r==KErrNotSupported);		// Caps reports it is not supported
+			}		
+		}	
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-229
+	@SYMTestCaseDesc 		Setting the audio configuration - audio encoding.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Read the audio capabilities of the playback channel. For each of the possible 3 audio 
+							encodings, issue a request on the playback channel to set this audio configuration.
+	@SYMTestExpectedResults	Either KErrNone if the playback channel supports the audio encoding, or
+							KErrNotSupported if the playback channel does not support the audio encoding. 
+	@SYMREQ					PREQ1073.4 */	
+		
+	Test.Next(_L("Try to set every possible encoding"));
+	TxSoundDevice.AudioFormat(PlayFormatBuf);	// Read back the current setting which must be valid.
+	for (i=0 ; i <= (TInt)ESoundEncoding24BitPCM ; i++)
+		{
+		PlayFormatBuf().iEncoding = (TSoundEncoding)i;
+		r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+		if (PlayCapsBuf().iEncodings & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			}					
+		else
+			{
+			CHECK(r==KErrNotSupported);		// Caps reports it is not supported
+			}		
+		}		
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-230
+	@SYMTestCaseDesc 		Setting the audio configuration - audio data format.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Read the audio capabilities of the playback channel. For each of the possible 2 audio data 
+							formats, issue a request on the playback channel to set this audio configuration.
+	@SYMTestExpectedResults	Either KErrNone if the playback channel supports the audio data format, or
+							KErrNotSupported if the playback channel does not support the audio data format. 
+	@SYMREQ					PREQ1073.4 */	
+	
+	Test.Next(_L("Try to set every possible data format"));
+	TxSoundDevice.AudioFormat(PlayFormatBuf);	// Read back the current setting which must be valid.
+	for (i=0 ; i <= (TInt)ESoundDataFormatNonInterleaved ; i++)
+		{
+		PlayFormatBuf().iDataFormat = (TSoundDataFormat)i;
+		r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+		if (PlayCapsBuf().iDataFormats & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			}					
+		else
+			{
+			CHECK(r==KErrNotSupported);		// Caps reports it is not supported
+			}		
+		}
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-231
+	@SYMTestCaseDesc 		Setting the audio configuration - altering the configuration while transferring data.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	Read the audio capabilities of the playback channel and apply a playback audio 
+								configuration that is supported by channel. Set the play buffer configuration and 
+								then start playing data from one of the buffers. While still playing, attempt to alter 
+								the audio configuration of the playback channel.
+							2)	Read the audio capabilities of the record channel and apply an audio record 
+								configuration that is supported by channel. Set the record buffer configuration and 
+								then start recording data into one of the buffers. While still recording, attempt 
+								to alter the audio configuration of the record channel.
+	@SYMTestExpectedResults	1)	Altering the audio configuration should fail with KErrInUse. 
+							2)	Altering the audio configuration should fail with KErrInUse.
+	@SYMREQ					PREQ1073.4 */
+		
+	Test.Next(_L("Try to alter the audio format while playing"));
+
+	// Set the audio configuration of the playback channel ready to start playing
+	TxSoundDevice.AudioFormat(PlayFormatBuf);	// Read back the current setting which must be valid.
+	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
+		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
+
+	PlayFormatBuf().iChannels = 2;
+	
+	// find first supported rate and set the the audio configuration to use it
+	TxSoundDevice.AudioFormat(PlayFormatBuf);	// Read back the current setting which must be valid.
+	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
+		{
+		PlayFormatBuf().iRate = (TSoundRate)i;
+		r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+		if (PlayCapsBuf().iRates & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			break;
+			}					
+		}	
+	
+	PrintConfig(PlayFormatBuf(),Test);
+	r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+	CHECK_NOERROR(r);
+	
+	// Set the play buffer configuration.
+	RChunk chunk;
+	TInt bufSize=BytesPerSecond(PlayFormatBuf()); 										// Large enough to hold 1 second of data.
+	bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
+	TTestSharedChunkBufConfig bufferConfig;
+	bufferConfig.iNumBuffers=3;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iFlags=0;	
+	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
+	r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	TxSoundDevice.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
+	
+	// Start playing
+	r=MakeSineTable(PlayFormatBuf());
+	CHECK_NOERROR(r);
+	r=SetToneFrequency(660,PlayFormatBuf());
+	CHECK_NOERROR(r);
+	TPtr8 ptr(chunk.Base()+bufferConfig.iBufferOffsetList[0],bufSize);
+	WriteTone(ptr,PlayFormatBuf());
+	TRequestStatus stat;
+	TxSoundDevice.PlayData(stat,bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
+
+	// Check that altering the audio format while playing - fails
+	r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+	CHECK(r==KErrInUse);
+
+	User::WaitForRequest(stat);
+	CHECK_EQUAL(stat.Int(),KErrNone);
+	
+	Test.Next(_L("Try to alter the audio format while recording"));
+	
+	// Set the audio configuration of the record channel ready to start recording
+	RxSoundDevice.AudioFormat(RecordFormatBuf);	// Read back the current setting which must be valid.
+	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
+		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
+	RecordFormatBuf().iChannels = 2;
+
+	// find first supported rate and set the the audio configuration to use it
+	for (i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
+		{
+		RecordFormatBuf().iRate = (TSoundRate)i;
+		r=TxSoundDevice.SetAudioFormat(RecordFormatBuf);
+		if (RecordCapsBuf().iRates & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			break;
+			}					
+		}
+	
+	// Use the same shared chunk for recording
+	r=RxSoundDevice.SetBufferChunkOpen(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	
+	// Start recording
+	TInt length;
+	RxSoundDevice.RecordData(stat,length);
+	
+	// Check that altering the audio format while recording - fails
+	r=RxSoundDevice.SetAudioFormat(RecordFormatBuf);
+	CHECK(r==KErrInUse);
+	
+	User::WaitForRequest(stat);
+	TInt retOffset=stat.Int();
+	CHECK(retOffset>=0);
+	CHECK(length>0);
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK_NOERROR(r);
+	
+	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
+	chunk.Close();
+	}
+
+LOCAL_C void TestSetBufferConfig(TInt aBufferConfigFlags)
+	{
+	
+	Test.Printf(_L("Testing setting the buffer configuration\r\n"));
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-232
+	@SYMTestCaseDesc 		Setting the buffer configuration - varying the number of buffers.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Issue a request on the playback channel to create a shared chunk (i.e. using 
+							SetBufferChunkCreate()) with a buffer configuration containing a single buffer. Attempt 
+							to open the same shared chunk on the record channel (i.e. using SetBufferChunkOpen()). 
+							Then close the chunk.
+							Repeat this same sequence using buffer configurations containing 2 - 8 buffers.
+	@SYMTestExpectedResults	In every case the attempt to create and open the shared chunk should return KErrNone. 
+	@SYMREQ					PREQ1073.4 */	
+	
+	Test.Next(_L("Test creating/opening a chunk, varying the number of buffers "));
+	TInt r;
+	RChunk chunk;
+	TTestSharedChunkBufConfig bufferConfig;
+	bufferConfig.iBufferSizeInBytes=0x7FE0;			// 32K - 32 bytes
+	if (PlayCapsBuf().iRequestMinSize)
+		bufferConfig.iBufferSizeInBytes&=~(PlayCapsBuf().iRequestMinSize-1); 	// Assumes iRequestMinSize is same for play and record
+	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
+	
+	TInt i;
+	for (i=1 ; i<=8 ; i++)
+		{
+		bufferConfig.iFlags=aBufferConfigFlags;
+		bufferConfig.iNumBuffers=i;
+		
+		// Create the shared chunk on the play channel
+		r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+		CHECK_NOERROR(r);
+		TxSoundDevice.GetBufferConfig(bufferConfigBuf);
+		PrintBufferConf(bufferConfig,Test);
+		
+		// Open the same shared chunk on the record channel
+		r=RxSoundDevice.SetBufferChunkOpen(bufferConfigBuf,chunk);
+		CHECK_NOERROR(r);
+	
+		chunk.Close();
+		}
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-233
+	@SYMTestCaseDesc 		Setting the buffer configuration - varying the size of the buffers.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Issue a request on the playback channel to create a shared chunk (i.e. using 
+							SetBufferChunkCreate()) with a buffer configuration containing multiple buffers 
+							each of size 32K bytes. Attempt to open the same shared chunk on the record channel 
+							(i.e. using SetBufferChunkOpen()). Then close the chunk. Repeat this same sequence 
+							using buffer configurations containing buffers of size 16K, 8K and 4K bytes. 
+	@SYMTestExpectedResults	In every case the attempt to create and open the shared chunk should return KErrNone. 
+	@SYMREQ					PREQ1073.4 */		
+		
+	Test.Next(_L("Test creating/opening a chunk, varying the size of the buffers "));
+	bufferConfig.iNumBuffers=4;
+	
+	for (i=1 ; i<=8 ; i*=2)
+		{
+		bufferConfig.iFlags=aBufferConfigFlags;
+		bufferConfig.iBufferSizeInBytes=(0x8000/i);
+		
+		// Create the shared chunk on the play channel
+		r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+		CHECK_NOERROR(r);
+		TxSoundDevice.GetBufferConfig(bufferConfigBuf);
+		PrintBufferConf(bufferConfig,Test);
+		
+		// Open the same shared chunk on the record channel
+		r=RxSoundDevice.SetBufferChunkOpen(bufferConfigBuf,chunk);
+		CHECK_NOERROR(r);
+		
+		chunk.Close();
+		}
+		
+	// Try creating a shared chunk for the record channel specifying an illegal buffer size.
+	if (RecordCapsBuf().iRequestMinSize)
+		{
+		Test.Next(_L("Test creating a chunk, with an illegal buffer size"));
+		bufferConfig.iNumBuffers=1;
+		bufferConfig.iBufferSizeInBytes=0x1001;		// 4K + 1byte
+		bufferConfig.iFlags=aBufferConfigFlags;
+		r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+		CHECK(r==KErrArgument);
+		chunk.Close();		
+		}	
+			
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-234
+	@SYMTestCaseDesc 		Setting the buffer configuration - specifying the buffer offsets.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Issue a request on the record channel to create a shared chunk (i.e. 
+							using SetBufferChunkCreate()) with an buffer configuration containing multiple buffers 
+							where the offset of each buffer is specified by the client. Perform this test repeatedly 
+							with buffer offsets specified as follows:-
+							1)	Valid buffer offsets
+							2)	Offsets resulting on overlapping  buffers
+							3)	Offsets which aren't aligned with the request alignment restrictions for the device (if it has any).
+	@SYMTestExpectedResults	1)	Setting the buffer configuration should return KErrNone. 
+							2)	Setting the buffer configuration should fail with KErrArgument.
+							3)	Setting the buffer configuration should fail with KErrArgument.
+	@SYMREQ					PREQ1073.4 */			
+/*		
+	// ***** Setting the buffer configuration - specifying the buffer offsets is not supported. *****
+	
+	Test.Next(_L("Test creating a chunk, specifying the buffer offsets"));
+	TInt bufSize=0x2000;
+	bufferConfig.iNumBuffers=8;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iBufferOffsetList[0]=0;
+	bufferConfig.iBufferOffsetList[1]=bufSize;
+	bufferConfig.iBufferOffsetList[2]=bufSize*4;
+	bufferConfig.iBufferOffsetList[3]=bufSize*6;
+	bufferConfig.iBufferOffsetList[4]=bufSize*7;
+	bufferConfig.iBufferOffsetList[5]=bufSize*9;
+	bufferConfig.iBufferOffsetList[6]=bufSize*10;
+	bufferConfig.iBufferOffsetList[7]=bufSize*12;
+	bufferConfig.iFlags=(aBufferConfigFlags|KScFlagBufOffsetListInUse);
+	bufferConfigBuf.SetLength(sizeof(bufferConfig));	// Otherwise set shorter by previous GetBufferConfig().
+	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	chunk.Close();	
+	
+	Test.Next(_L("Test creating a chunk, with invalid buffer offsets specified"));
+	
+	// Firstly with 2nd buffer overlapping the 1st
+	bufSize=0x2000;
+	bufferConfig.iNumBuffers=3;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iBufferOffsetList[0]=0;
+	bufferConfig.iBufferOffsetList[1]=bufSize/2;
+	bufferConfig.iBufferOffsetList[2]=bufSize*2;
+	bufferConfig.iFlags=(aBufferConfigFlags|KScFlagBufOffsetListInUse);
+	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK(r==KErrArgument);
+	chunk.Close();	
+	
+	// Now with offset of 3rd buffer not on a page boundary
+	if (RecordCapsBuf().iRequestAlignment)
+		{
+		bufSize=0x2000;
+		bufferConfig.iNumBuffers=3;
+		bufferConfig.iBufferSizeInBytes=bufSize;
+		bufferConfig.iBufferOffsetList[0]=0;
+		bufferConfig.iBufferOffsetList[1]=bufSize;
+		bufferConfig.iBufferOffsetList[2]=(bufSize*2)+1;
+		bufferConfig.iFlags=(aBufferConfigFlags|KScFlagBufOffsetListInUse);
+		r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+		CHECK(r==KErrArgument);
+		chunk.Close();		
+		}
+*/		
+	}
+
+LOCAL_C void TestPlay()
+	{
+	
+	Test.Printf(_L("Testing play operation\r\n"));
+	
+	// Close and re-open the playback channel to reset the driver.
+	TxSoundDevice.Close();
+	TInt r = TxSoundDevice.Open(KSoundScTxUnit0);
+	CHECK_NOERROR(r);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-235
+	@SYMTestCaseDesc 		Play operation - playing without having set the buffer configuration.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Issue a request on the playback channel to play some audio data before having set-up 
+							the buffer configuration.
+	@SYMTestExpectedResults	The play request should fail with KErrNotReady.
+	@SYMREQ					PREQ1073.4 */			
+	
+	Test.Next(_L("Test playing without setting buffer config"));
+	TRequestStatus stat[2];
+	TxSoundDevice.PlayData(stat[0],0,0x2000);	// 8K
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrNotReady);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-236
+	@SYMTestCaseDesc 		Play operation - playing without having set the audio configuration.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the buffer configuration on the playback channel and then issue a request to 
+							play audio data before having set-up the audio configuration
+	@SYMTestExpectedResults	The play request should complete with KErrNone - with the driver using its default 
+							audio configuration for the transfer.
+	@SYMREQ					PREQ1073.4 */	
+	
+	Test.Next(_L("Test playing without setting audio config"));
+	
+	// Read back the default play configuration
+	TxSoundDevice.AudioFormat(PlayFormatBuf);
+	TCurrentSoundFormatV02 playFormat=PlayFormatBuf();
+	PrintConfig(playFormat,Test);
+	
+	// Set the play buffer configuration.
+	RChunk chunk;
+	TInt bufSize=BytesPerSecond(PlayFormatBuf()); 										// Large enough to hold 1 second of data.
+	bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
+	TTestSharedChunkBufConfig bufferConfig;
+	bufferConfig.iNumBuffers=1;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iFlags=0;	
+	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
+	r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	TxSoundDevice.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
+	
+	// Start playing
+	r=MakeSineTable(PlayFormatBuf());
+	CHECK_NOERROR(r);
+	r=SetToneFrequency(660,PlayFormatBuf());
+	CHECK_NOERROR(r); 
+	TPtr8 ptr(chunk.Base()+bufferConfig.iBufferOffsetList[0],bufSize);
+	WriteTone(ptr,PlayFormatBuf());
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_NOERROR(stat[0].Int());
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-239
+	@SYMTestCaseDesc 		Play operation - with invalid arguments.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the playback channel to commence playing audio data using a buffer configuration 
+							containing multiple buffers. Now issue a series of transfer requests to play data where the 
+							requests contain invalid request arguments as follows:-
+							1)	A request with a buffer offset before the start of the first buffer.
+							2)	A request with a buffer offset between buffers.
+							3)	A request with a length too large for a buffer.
+							4)	A request with a buffer offset that doesn't comply with the offset restrictions of 
+								the driver (i.e. TSoundFormatsSupportedV02:: iRequestAlignment).
+							5)	A request with a length that doesn't comply with the length restrictions of 
+								the driver (i.e. TSoundFormatsSupportedV02::iRequestMinSize).
+	@SYMTestExpectedResults	1)	The play request should fail with KErrArgument.
+							2)	The play request should fail with KErrArgument.
+							3)	The play request should fail with KErrArgument.
+							4)	The play request should fail with KErrArgument.
+							5)	The play request should fail with KErrArgument
+	@SYMREQ					PREQ1073.4 */	
+	
+	Test.Next(_L("Test playing with invalid arguments"));
+	
+	// With a buffer offset before the start of the buffer.
+	TxSoundDevice.PlayData(stat[0],(bufferConfig.iBufferOffsetList[0]-0x100),bufSize,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrArgument);
+	
+	// With a buffer offset beyond the end of the buffer
+	TxSoundDevice.PlayData(stat[0],(bufferConfig.iBufferOffsetList[0]+bufSize+0x100),bufSize,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrArgument);
+	
+	// With a length too large for the buffer
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],(bufSize+0x100),KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrArgument);
+	
+	// With a length that doesn't comply with the length restrictions of the driver
+	if (PlayCapsBuf().iRequestMinSize)
+		{
+		TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],(bufSize-1),KSndFlagLastSample);
+		User::WaitForRequest(stat[0]);
+		CHECK_EQUAL(stat[0].Int(),KErrArgument);
+		}
+		
+	// With an offset that doesn't comply with the offset restrictions of the driver
+	if (PlayCapsBuf().iRequestAlignment)
+		{
+		TInt ln=bufSize/2;
+		if (PlayCapsBuf().iRequestMinSize)
+			ln&=~(PlayCapsBuf().iRequestMinSize-1);	// Keep the buffer length valid for the driver.
+		TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0]+1,ln,KSndFlagLastSample);
+		User::WaitForRequest(stat[0]);
+		CHECK_EQUAL(stat[0].Int(),KErrArgument);
+		}	
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-242
+	@SYMTestCaseDesc 		Play operation - play underflow detection.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the audio configuration on the playback channel and then setup the buffer 
+							configuration. Issue a single request to play audio data from one of the buffers 
+							(without supplying the KSndFlagLastSample flag) and wait for the request to complete.
+	@SYMTestExpectedResults	The driver should successfully play the audio data supplied but the request should 
+							return the error value: KErrUnderflow.
+	@SYMREQ					PREQ1073.4 */		
+	
+	Test.Next(_L("Test play underflow detection"));
+	
+	// Now set the audio configuration to a known state.
+	if (PlayCapsBuf().iEncodings&KSoundEncoding16BitPCM)
+		PlayFormatBuf().iEncoding = ESoundEncoding16BitPCM;
+	if (PlayCapsBuf().iRates&KSoundRate16000Hz)
+		PlayFormatBuf().iRate = ESoundRate16000Hz;
+	if (PlayCapsBuf().iChannels&KSoundStereoChannel)
+		PlayFormatBuf().iChannels = 2;
+	PrintConfig(PlayFormatBuf(),Test);
+	r=TxSoundDevice.SetAudioFormat(PlayFormatBuf);
+	CHECK_NOERROR(r);
+	
+	// Reset the play buffer configuration to correspond to the audio configuration.
+	bufSize=BytesPerSecond(PlayFormatBuf()); 											// Large enough to hold 1 second of data (64K)
+	bufSize=ValidBufferSize(bufSize,PlayCapsBuf().iRequestMinSize,PlayFormatBuf());		// Keep the buffer length valid for driver.
+	bufferConfig.iNumBuffers=1;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iFlags=0;	
+	r=TxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	TxSoundDevice.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
+	
+	// Start playing
+	r=MakeSineTable(PlayFormatBuf());
+	CHECK_NOERROR(r);
+	r=SetToneFrequency(660,PlayFormatBuf());
+	CHECK_NOERROR(r); 
+	ptr.Set(chunk.Base()+bufferConfig.iBufferOffsetList[0],bufSize,bufSize);
+	WriteTone(ptr,PlayFormatBuf());
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize);
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrUnderflow);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-243
+	@SYMTestCaseDesc 		Play operation - playing multiple transfers from a single buffer.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the audio configuration on the playback channel and setup the buffer configuration 
+							so the shared chunk contains just a single large buffer. Issue a pair of requests to play 
+							audio data from the buffer (marking the last with the KSndFlagLastSample flag) and wait 
+							for the requests to complete.
+	@SYMTestExpectedResults	The driver should successfully play the audio data supplied and both requests should 
+							complete with KErrNone.
+	@SYMREQ					PREQ1073.4 */	
+	
+	Test.Next(_L("Test playing multiple transfers from a single buffer"));
+	
+	// Start playing
+	TInt len=bufSize/2;
+	if (PlayCapsBuf().iRequestMinSize)
+		len&=~(PlayCapsBuf().iRequestMinSize-1);	// Keep the buffer length valid for the driver.
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],len);
+	TxSoundDevice.PlayData(stat[1],(bufferConfig.iBufferOffsetList[0]+len),len,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_NOERROR(stat[0].Int());
+	User::WaitForRequest(stat[1]);
+	CHECK_NOERROR(stat[1].Int());
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-244
+	@SYMTestCaseDesc 		Play operation - tracking the count of bytes transferred.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the playback channel for playing audio data. 
+							1)	Reset the channel's count of bytes transferred and read back the count.
+							2)	Issue a play request of known length and wait for it to complete. Now read the 
+								count of bytes transferred.
+							3)	Reset the channel's count of bytes transferred and read back the count.
+	@SYMTestExpectedResults	1)	The count of bytes transferred should equal zero.
+							2)	The count of bytes transferred should equal the length of the play request.
+							3)	The count of bytes transferred should equal zero.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test tracking the number of bytes played"));
+	TxSoundDevice.ResetBytesTransferred();
+	TInt bytesPlayed=TxSoundDevice.BytesTransferred();
+	CHECK(bytesPlayed==0);
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],len,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_NOERROR(stat[0].Int());
+	bytesPlayed=TxSoundDevice.BytesTransferred();
+	CHECK(bytesPlayed==len);
+	TxSoundDevice.ResetBytesTransferred();
+	bytesPlayed=TxSoundDevice.BytesTransferred();
+	CHECK(bytesPlayed==0);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-246
+	@SYMTestCaseDesc 		Play operation - testing the driver's handling of PDD play errors.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the playback channel for playing audio data. Using the CustomConfig() test mode 
+							supported by the driver, induce the following errors returned from the driver PDD back 
+							to the LDD:-
+								1)	Induce a KErrTimedOut error at the start of the transfer and then issue a play request.
+								2)	Induce a KErrTimedOut error once transfer has commenced and then issue a play request. 
+								Once this completes, issue a further play request.
+	@SYMTestExpectedResults	1)	The play request should fail immediately with KErrTimedOut (with no audible output being 
+								heard).
+							2)	The driver should output a short section of audible data before the first play request 
+								fails with KErrTimedOut. However, the driver should recover from this and the second 
+								play request should complete with KErrNone.
+	@SYMREQ					PREQ1073.4 */
+	
+#ifdef _DEBUG	
+	Test.Next(_L("Test the driver's handling of PDD play errors"));
+	
+	// First induce an error at the start of the transfer
+	// Use an LDD test mode which induces KErrTimedOut at the start of the transfer.
+	r=TxSoundDevice.CustomConfig(KSndCustom_ForceStartTransferError);
+	CHECK_NOERROR(r);
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrTimedOut);
+	
+	// Now induce an error once transfer has commenced
+	// Use an LDD test mode which induces KErrTimedOut once transfer has commenced.
+	r=TxSoundDevice.CustomConfig(KSndCustom_ForceTransferDataError);
+	CHECK_NOERROR(r);
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_EQUAL(stat[0].Int(),KErrTimedOut);
+	
+	// Check that the driver recovers
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
+	User::WaitForRequest(stat[0]);
+	CHECK_NOERROR(stat[0].Int());
+#endif	
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-247
+	@SYMTestCaseDesc 		Play operation - closing the channel cancels any play requests.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the playback channel for playing audio data. Issue a play request and 
+							while this is outstanding, close the playback channel.
+	@SYMTestExpectedResults	The outstanding request should complete with KErrCancel.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test that closing the channel cancels a play request"));
+	TxSoundDevice.PlayData(stat[0],bufferConfig.iBufferOffsetList[0],len,KSndFlagLastSample);
+	CHECK(stat[0]==KRequestPending);
+	TxSoundDevice.Close();
+	User::WaitForRequest(stat[0]);
+	CHECK(stat[0]==KErrCancel);
+	
+	Test.Next(_L("Re-open the channel"));
+	r = TxSoundDevice.Open(KSoundScTxUnit0);
+	CHECK_NOERROR(r);
+	
+	chunk.Close();
+	}
+	
+LOCAL_C void TestRecord()
+	{
+	
+	Test.Printf(_L("Testing record operation\r\n"));
+	
+	// Close and re-open the record channel to reset the driver.
+	RxSoundDevice.Close();
+	TInt r = RxSoundDevice.Open(KSoundScRxUnit0);
+	CHECK_NOERROR(r);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-251
+	@SYMTestCaseDesc 		Record operation - recording without having set the buffer configuration.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Issue a request on the record channel to record some audio data before 
+							having set-up the buffer configuration.
+	@SYMTestExpectedResults	The record request should fail with KErrNotReady.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test recording without setting buffer config"));
+	
+	TRequestStatus stat;
+	TInt length;
+	RxSoundDevice.RecordData(stat,length);
+	User::WaitForRequest(stat);
+	TInt retOffset=stat.Int();
+	CHECK_EQUAL(retOffset,KErrNotReady);
+	
+	// Test releasing a buffer without setting buffer config
+	r=RxSoundDevice.ReleaseBuffer(0);
+	CHECK(r==KErrNotReady);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-252
+	@SYMTestCaseDesc 		Record operation - recording without having set the audio configuration.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the buffer configuration on the record channel. 
+							1)	Issue a request to record a buffer of audio data before having set-up the audio 
+								configuration.
+							2)	Release the buffer.
+	@SYMTestExpectedResults	1)	The record request should complete with KErrNone - with the driver using its 
+								default audio configuration for the transfer.
+							2)	The request to release the buffer should return KErrNone
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test recording without setting audio config"));
+	
+	// Read back the default record configuration
+	RxSoundDevice.AudioFormat(RecordFormatBuf);
+	TCurrentSoundFormatV02 recordFormat=RecordFormatBuf();
+	PrintConfig(recordFormat,Test);
+	
+	// Set the record buffer configuration.
+	RChunk chunk;
+	TInt bufSize=BytesPerSecond(RecordFormatBuf()); 										// Large enough to hold 1 second of data.
+	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());		// Keep the buffer length valid for driver.
+	TTestSharedChunkBufConfig bufferConfig;
+	bufferConfig.iNumBuffers=3;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iFlags=0;	
+	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
+	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
+	
+	// Start recording
+	RxSoundDevice.SetVolume(KSoundMaxVolume);
+	RxSoundDevice.RecordData(stat,length);		// Start recording here
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset>=0);
+	CHECK(length==bufSize);
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK_NOERROR(r);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-255
+	@SYMTestCaseDesc 		Record operation - invalid attempts to release a record buffer.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the record channel to record audio data. Issue a request to record a buffer of audio data
+							and then release the buffer.
+							1)	Request to release the same buffer just released (without having re-claimed it with a 
+								further record request).
+							2)	Release a further buffer - specifying an illegal buffer offset for the buffer.
+							3)	Stop the driver from recording (using CancelRecordData()). Now release a buffer while 
+								recording is disabled.
+	@SYMTestExpectedResults	1)	The request to release the buffer should fail with KErrNotFound.
+							2)	The request to release the buffer should fail with KErrNotFound.
+							3)	The request to release the buffer should fail with KErrNotFound.
+	@SYMREQ					PREQ1073.4 */
+	
+	// Test releasing a buffer twice
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK(r==KErrNotFound);
+	
+	// Test releasing an invalid buffer offset
+	r=RxSoundDevice.ReleaseBuffer(0);
+	CHECK(r==KErrNotFound);
+	
+	// Third test case for PBASE-T_SOUND_API-255 is performed later in this function.
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-256
+	@SYMTestCaseDesc 		Record operation - record overflow detection.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the audio configuration on the record channel and then setup the buffer configuration 
+							so the shared chunk contains three record buffers.
+							1)	Issue a request to record a buffer of audio data (to start the driver recording).
+							2)	When the request completes, release the buffer immediately.
+							3)	Wait just over 2 buffer periods (i.e. the time it takes for the driver to fill 2 record 
+								buffers) and then issue a further record request.
+							4)	To test that the driver recovers from the overflow situation, immediately issue a further 
+								record request. 
+	@SYMTestExpectedResults	1)	The record request should complete with KErrNone.
+							2)	The request to release the buffer should return KErrNone.
+							3)	The record request should fail with KErrOverflow.
+							4)	The record request should complete with KErrNone.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test for record overflow"));
+
+	// Now set the audio configuration to a known state.
+	RxSoundDevice.CancelRecordData();	// Stop the driver from recording.
+
+	RxSoundDevice.AudioFormat(RecordFormatBuf);	// Read back the current setting which must be valid.
+	if (RecordCapsBuf().iEncodings&KSoundEncoding16BitPCM)
+		RecordFormatBuf().iEncoding = ESoundEncoding16BitPCM;
+	if (RecordCapsBuf().iChannels&KSoundStereoChannel)
+		RecordFormatBuf().iChannels = 2;
+
+	// find first supported rate and set the the audio configuration to use it
+	for (TInt i=0 ; i <= (TInt)ESoundRate48000Hz ; i++)
+		{
+		RecordFormatBuf().iRate = (TSoundRate)i;
+		r = RxSoundDevice.SetAudioFormat(RecordFormatBuf);
+		if (RecordCapsBuf().iRates & (1<<i))
+			{
+			CHECK_NOERROR(r);				// Caps reports it is supported
+			break;
+			}					
+		}
+
+	PrintConfig(RecordFormatBuf(),Test);
+	
+	// Reset the record buffer configuration to correspond to the audio configuration.
+	bufSize=BytesPerSecond(RecordFormatBuf())/2; 	 										// Large enough to hold 0.5 seconds of data (64K)
+	bufSize=ValidBufferSize(bufSize,RecordCapsBuf().iRequestMinSize,RecordFormatBuf());		// Keep the buffer length valid for driver.
+	bufferConfig.iNumBuffers=3;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iFlags=0;	
+	r=RxSoundDevice.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	CHECK_NOERROR(r);
+	RxSoundDevice.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	CHECK(bufferConfig.iBufferSizeInBytes==bufSize);
+	
+	// Test releasing a buffer before we have started recording
+	r=RxSoundDevice.ReleaseBuffer(bufferConfig.iBufferOffsetList[0]);
+	CHECK(r==KErrNotFound);
+	
+	RxSoundDevice.RecordData(stat,length);	// Start recording here
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset>=0);
+	CHECK(length==bufSize);
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK_NOERROR(r);
+	
+	User::After(1100000); // Wait 2 buffer periods (1.1 seconds) for data overflow. 
+	
+	RxSoundDevice.RecordData(stat,length);
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset==KErrOverflow);
+	
+	Test.Next(_L("Test that the driver recovers from overflow"));
+	
+	RxSoundDevice.RecordData(stat,length);
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset>=0);
+	CHECK(length==bufSize);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-257
+	@SYMTestCaseDesc 		Record operation - when client is too slow releasing buffers.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the audio configuration on the record channel and then setup the buffer configuration 
+							so the shared chunk contains three record buffers. Issue a request to record a buffer of 
+							audio data (to start the driver recording). When this request completes, issue a further 
+							record request without releasing the first buffer.
+	@SYMTestExpectedResults	The second record request should fail with KErrInUse.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test when client is too slow releasing buffers"));
+	
+	RxSoundDevice.RecordData(stat,length);
+	User::WaitForRequest(stat);
+	TInt retOffset1=stat.Int();
+	CHECK(retOffset1==KErrInUse);	
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK_NOERROR(r);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-258
+	@SYMTestCaseDesc 		Record operation - tracking the count of bytes transferred.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the record channel for recording audio data. 
+							1)	Reset the channel's count of bytes transferred and read back the count.
+							2)	Issue a record request (to start the driver recording) and wait for it to complete. Immediately read the count of bytes transferred.
+							3)	Reset the channel's count of bytes transferred and read back the count
+	@SYMTestExpectedResults	1)	The count of bytes transferred should equal zero.
+							2)	The count of bytes transferred should equal the size of a record buffer.
+							3)	The count of bytes transferred should equal zero.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test tracking the number of bytes recorded"));
+	RxSoundDevice.CancelRecordData();				// Stop the driver from recording.
+	RxSoundDevice.ResetBytesTransferred();
+	TInt bytesRecorded=RxSoundDevice.BytesTransferred();
+	CHECK(bytesRecorded==0);
+	RxSoundDevice.RecordData(stat,length);			// Re-start recording here
+	User::WaitForRequest(stat);
+	
+	// Quickly check the number of bytes recorded
+	bytesRecorded=RxSoundDevice.BytesTransferred();
+	CHECK(bytesRecorded==bufSize);
+	
+	// Now check the request was successful and release the buffer
+	retOffset=stat.Int();
+	CHECK(retOffset>=0);
+	CHECK(length==bufSize);
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK_NOERROR(r);
+	
+	RxSoundDevice.ResetBytesTransferred();
+	bytesRecorded=RxSoundDevice.BytesTransferred();
+	CHECK(bytesRecorded==0);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-260
+	@SYMTestCaseDesc 		Record operation - testing the driver's handling of PDD record errors.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Setup the record channel for recording. Using the CustomConfig() test mode supported by the driver, induce 
+							the following errors returned from the driver PDD back to the LDD:-
+							1)	Induce a KErrTimedOut error at the start of the transfer. Then, issue a record request to 
+								start the driver recording. Once this completes, stop the channel from recording. 
+							2)	Induce a KErrTimedOut error once transfer has commenced. Then, issue a record request to 
+								re-start the driver recording. Once this completes, issue a further record request.
+	@SYMTestExpectedResults	1)	The record request should fail immediately with KErrTimedOut. 
+							2)	The first record request should soon fail with KErrTimedOut. However, the driver should 
+								recover from this and the subsequent record request should complete with KErrNone.
+	@SYMREQ					PREQ1073.4 */
+	
+#ifdef _DEBUG	
+	Test.Next(_L("Test the driver's handling of PDD record errors"));
+	
+	Test.Printf(_L("Induce an error at the start of the transfer.\r\n"));
+	// Use an LDD test mode which induces KErrTimedOut at the start of the transfer.
+	RxSoundDevice.CancelRecordData();				// Stop the driver from recording.
+	r=RxSoundDevice.CustomConfig(KSndCustom_ForceStartTransferError);
+	CHECK_NOERROR(r);
+	RxSoundDevice.RecordData(stat,length);			// Re-start recording here
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset==KErrTimedOut);
+	RxSoundDevice.CancelRecordData();				// Stop the driver from recording.
+	
+	Test.Printf(_L("Induce an error once transfer has commenced.\r\n"));
+	// Use an LDD test mode which induces KErrTimedOut once transfer has commenced.
+	r=RxSoundDevice.CustomConfig(KSndCustom_ForceTransferDataError);
+	CHECK_NOERROR(r);
+	RxSoundDevice.RecordData(stat,length);			// Re-start recording here
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset==KErrTimedOut);
+	
+	Test.Printf(_L("Check that the driver recovers.\r\n"));
+	RxSoundDevice.RecordData(stat,length);
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	CHECK(retOffset>=0);
+	CHECK(length==bufSize);
+	r=RxSoundDevice.ReleaseBuffer(retOffset);
+	CHECK_NOERROR(r);
+	
+/*	Test disabled 	
+	Test.Printf(_L("Induce LDD to be slow servicing transfer completes from PDD.\r\n"));
+	r=RxSoundDevice.CustomConfig(KSndCustom_ForceTransferTimeout);
+	CHECK_NOERROR(r);
+	RxSoundDevice.RecordData(stat,length);
+	User::WaitForRequest(stat);
+	retOffset=stat.Int();
+	Test.Printf(_L("Driver returned %d.\r\n"),retOffset); */
+#endif	
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-261
+	@SYMTestCaseDesc 		Record operation - closing the channel cancels any record requests.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			Start the record channel for recording audio data. Issue a record request and while this is 
+							outstanding, close the record channel
+	@SYMTestExpectedResults	The outstanding request should complete with KErrCancel.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Test that closing the channel cancels a play request"));
+	RxSoundDevice.RecordData(stat,length);
+	CHECK(stat==KRequestPending);
+	RxSoundDevice.Close();
+	User::WaitForRequest(stat);
+	CHECK(stat==KErrCancel);
+	
+	Test.Next(_L("Re-open the channel"));
+	r = RxSoundDevice.Open(KSoundScRxUnit0);
+	CHECK_NOERROR(r);
+	
+	chunk.Close();
+	}
+
+#ifdef _DEBUG
+LOCAL_C void TestChangeOfHwConfigNotifier()
+	{
+	
+	Test.Printf(_L("Testing the change of h/w config notifier\r\n"));
+	
+	// If support for the notifier is not supported on this platform, use a debug custom config command to force
+	// support for the notifier.
+	TInt r;
+	if (!PlayCapsBuf().iHwConfigNotificationSupport)
+		{
+		r=TxSoundDevice.CustomConfig(KSndCustom_ForceHwConfigNotifSupported);
+		CHECK_NOERROR(r);
+		}
+		
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-264
+	@SYMTestCaseDesc 		Change of h/w config. notifier - receiving notification.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	Register for notification of a change in the hardware configuration of the device on 
+								either the record or playback channel. Using the CustomConfig() test mode supported by the 
+								driver, trigger the notifier - signalling that the headset is not present.
+							2) 	Re-register for notification of a change in the hardware configuration on the same channel.
+								Again using the CustomConfig() test mode, trigger the notifier - this time signalling that the 
+								headset is present.
+	@SYMTestExpectedResults	1)	The outstanding request for notification should complete with KErrNone and the status of 
+								the bolean aHeadsetPresent should be false.
+							2)	The outstanding request for notification should complete with KErrNone and the status of
+								the bolean aHeadsetPresent should be true.
+	@SYMREQ					PREQ1073.4 */	
+	
+	// Register for notification of a change in the hardware configuration of the device.
+	TRequestStatus stat;
+	TBool headsetPresent=ETrue;
+	TxSoundDevice.NotifyChangeOfHwConfig(stat,headsetPresent);
+	CHECK(stat==KRequestPending);
+	
+	Test.Next(_L("Trigger the notifier"));
+	// Use another debug custom config command to trigger the notifier.
+	r=TxSoundDevice.CustomConfig(KSndCustom_CompleteChangeOfHwConfig,(TAny*)0x00);	// Signal headset not present.
+	CHECK_NOERROR(r);
+	User::WaitForRequest(stat);
+	CHECK_NOERROR(stat.Int());
+	CHECK(!headsetPresent);
+	
+	Test.Next(_L("Trigger the notifier again"));
+	TxSoundDevice.NotifyChangeOfHwConfig(stat,headsetPresent);
+	CHECK(stat==KRequestPending);
+	r=TxSoundDevice.CustomConfig(KSndCustom_CompleteChangeOfHwConfig,(TAny*)0x01);	// Signal headset is present.
+	CHECK_NOERROR(r);
+	User::WaitForRequest(stat);
+	CHECK_NOERROR(stat.Int());
+	CHECK(headsetPresent);
+	
+	Test.Next(_L("Test cancelling the notifier"));
+	TxSoundDevice.NotifyChangeOfHwConfig(stat,headsetPresent);
+	CHECK(stat==KRequestPending);
+	TxSoundDevice.CancelNotifyChangeOfHwConfig();
+	User::WaitForRequest(stat);
+	CHECK(stat==KErrCancel);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-265
+	@SYMTestCaseDesc 		Change of h/w config. notifier - receiving notification.
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	Register for notification of a change in the hardware configuration of the device on 
+								either the record or playback channel. Using the CustomConfig() test mode supported by the 
+								driver, trigger the notifier - signalling that the headset is not present.
+							2) 	Re-register for notification of a change in the hardware configuration on the same channel.
+								Again using the CustomConfig() test mode, trigger the notifier - this time signalling that the 
+								headset is present.
+	@SYMTestExpectedResults	1)	The outstanding request for notification should complete with KErrNone and the status of 
+								the bolean aHeadsetPresent should be false.
+							2)	The outstanding request for notification should complete with KErrNone and the status of
+								the bolean aHeadsetPresent should be true.
+	@SYMREQ					PREQ1073.4 */	
+	
+	Test.Next(_L("Test that closing the channel cancels the notifier"));
+	TxSoundDevice.NotifyChangeOfHwConfig(stat,headsetPresent);
+	CHECK(stat==KRequestPending);
+	TxSoundDevice.Close();
+	User::WaitForRequest(stat);
+	CHECK(stat==KErrCancel);
+	
+	Test.Next(_L("Re-open the channel"));
+	r = TxSoundDevice.Open(KSoundScTxUnit0);
+	CHECK_NOERROR(r);
+	}
+#endif	
+	
+LOCAL_C void TestUnloadDrivers()
+	{
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-221
+	@SYMTestCaseDesc 		Un-installing the LDD
+	@SYMTestPriority 		Critical
+	@SYMTestActions 		Attempt to un-install the LDD (using User::FreeLogicalDevice()). 
+	@SYMTestExpectedResults KErrNone - LDD unloads successfully 
+	@SYMREQ					PREQ1073.4 */
+	
+	TInt r=User::FreeLogicalDevice(KDevSoundScName);
+	Test.Printf(_L("Unloading %S.LDD - %d\r\n"),&KDevSoundScName,r);
+	CHECK_NOERROR(r);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-222
+	@SYMTestCaseDesc 		Un-installing the PDD
+	@SYMTestPriority 		Critical
+	@SYMTestActions 		Attempt to un-install the PDD (using User::FreePhysicalDevice()). 
+	@SYMTestExpectedResults KErrNone - PDD unloads successfully 
+	@SYMREQ					PREQ1073.4 */
+	
+	TName pddName(KDevSoundScName);
+	_LIT(KPddWildcardExtension,".*");
+	pddName.Append(KPddWildcardExtension);
+	TFindPhysicalDevice findPD(pddName);
+	TFullName findResult;
+	r=findPD.Next(findResult);
+	while (r==KErrNone)
+		{
+		r=User::FreePhysicalDevice(findResult);
+		Test.Printf(_L("Unloading %S.PDD - %d\r\n"),&findResult,r);
+		CHECK_NOERROR(r);
+		findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container.
+		r=findPD.Next(findResult);
+		} 
+	}
+
+/**
+Invoke the helper executable, tell it what unit to open RSoundSc for.
+
+@param aUnit Parameter to supply to RSoundSc ie. KSoundScTxUnit0, KSoundScRxUnit0
+@param aExpectedError The expected return code from RSoundSc::Open
+ */
+static void RunHelper(TInt aUnit, TInt aExpectedError)
+	{
+	TInt r;
+	
+	RProcess ph;
+	r = ph.Create(KHelperExe, KNullDesC);
+	CHECK_NOERROR(r);
+	r = ph.SetParameter(KSlot, aUnit); 
+	CHECK_NOERROR(r);
+
+	TRequestStatus rsh;
+	ph.Logon(rsh);
+	Test(rsh == KRequestPending);
+	ph.Resume();
+	User::WaitForRequest(rsh);
+
+	// process has died so check the panic category and reason match the expected values
+	CHECK_EQUAL(ph.ExitType(), EExitPanic);
+	Test(ph.ExitCategory()==KSoundAPICaps,__LINE__,(const TText*)__FILE__);
+	CHECK_EQUAL(ph.ExitReason(), aExpectedError);
+
+	ph.Close();
+	}
+
+/**
+Delete the copy of the helper exe which was created with altered capabilities
+*/
+static TInt DeleteHelper()
+	{
+	RFs fs;
+	TInt r = fs.Connect();
+	CHECK_NOERROR(r);
+	TFileName fileName(KSysBin);
+	fileName.Append(KPathDelimiter);
+	fileName+=KHelperExe;
+	//delete modified version of helper exe
+	r = fs.Delete(fileName);
+	fs.Close();
+	return r;
+	}
+
+/**
+Use setcap.exe to create a copy of the helper executable, t_sound_api_helper.exe
+called t_sound_api_helper_caps.exe with the supplied capabilities.
+
+@param aCaps A bitmask of capabilities to assign to helper exe.
+*/
+static void SetHelperCaps(TUint32 aCaps)
+	{
+	TInt r;
+	_LIT(KCommandLineArgsFormat, "%S %08x %S\\%S");
+	TBuf<128> cmdLine;
+	cmdLine.Format(KCommandLineArgsFormat, &KHelperExeBase, aCaps, &KSysBin, &KHelperExe);
+
+	RProcess p;
+	r = p.Create(_L("setcap.exe"), cmdLine);
+	CHECK_NOERROR(r);
+
+	TRequestStatus rs;
+	p.Logon(rs);
+	CHECK_EQUAL(rs.Int(),KRequestPending);
+	p.Resume();
+	User::WaitForRequest(rs);
+
+	p.Close();
+	}
+
+/**
+Test that ECapabilityMultimediaDD is required
+in order to open RSoundSc for playback and that
+ECapabilityUserEnvironment is needed, in addition,
+to open for record.
+*/
+static void TestCapabilityChecks()
+	{
+	//convert capabilities into bitmask understood by setcap.exe
+	const TUint32 KUserEnvironment = 1<<ECapabilityUserEnvironment;
+	const TUint32 KMultimediaDD= 1<<ECapabilityMultimediaDD;
+	
+	//try to delete helper just in case it has been left hanging about from a previous run which failed
+	DeleteHelper();
+	SetHelperCaps(NULL);
+	RunHelper(KSoundScTxUnit0,KErrPermissionDenied);
+	RunHelper(KSoundScRxUnit0,KErrPermissionDenied);
+	
+	CHECK_NOERROR(DeleteHelper());
+	SetHelperCaps(KMultimediaDD);
+	RunHelper(KSoundScTxUnit0,KErrNone);
+	RunHelper(KSoundScRxUnit0,KErrPermissionDenied);
+
+	CHECK_NOERROR(DeleteHelper());
+	SetHelperCaps(KUserEnvironment);
+	RunHelper(KSoundScTxUnit0,KErrPermissionDenied);
+	RunHelper(KSoundScRxUnit0,KErrPermissionDenied);
+
+	CHECK_NOERROR(DeleteHelper());
+	SetHelperCaps(KUserEnvironment|KMultimediaDD);
+	RunHelper(KSoundScTxUnit0,KErrNone);
+	RunHelper(KSoundScRxUnit0,KErrNone);
+
+	CHECK_NOERROR(DeleteHelper());
+	}
+
+TInt E32Main()
+	{
+	TInt r;
+
+	__UHEAP_MARK;
+
+	Test.Title();
+
+	Test.Start(_L("Load"));
+	if (Load()==KErrNotFound)
+		{
+		Test.Printf(_L("Shared chunk sound driver not supported - test skipped\r\n"));
+		Test.End();
+		Test.Close();
+		__UHEAP_MARKEND;
+		return(KErrNone);
+		}
+
+	// The __KHEAP_MARK and __KHEAP_MARKEND macros unfortunately have to be commented out or they
+	// generate false positives on the x86pc target build.  This is to do with the launching of the
+	// helper executable, which results in another component allocating memory and not freeing it,
+	// thus causing the macros here to trigger a kern-exec 17 that is not related to the sound driver
+	// itself.  The same macros are fine on other platforms.  See DEF129273 for more information
+	//__KHEAP_MARK;
+
+	Test.Next(_L("Test Capability Checking"));
+	TestCapabilityChecks();
+		
+	Test.Next(_L("Open playback channel"));
+	r = TxSoundDevice.Open(KSoundScTxUnit0);
+	CHECK_NOERROR(r);
+	
+	Test.Next(_L("Open record channel"));
+	r = RxSoundDevice.Open(KSoundScRxUnit0);
+	CHECK_NOERROR(r);
+	
+	Test.Next(_L("Query play formats supported"));
+	TxSoundDevice.Caps(PlayCapsBuf);
+	TSoundFormatsSupportedV02 playCaps=PlayCapsBuf();
+	PrintCaps(playCaps,Test);
+
+	Test.Next(_L("Query record formats supported"));
+	RxSoundDevice.Caps(RecordCapsBuf);
+	TSoundFormatsSupportedV02 recordCaps=RecordCapsBuf();
+	PrintCaps(recordCaps,Test);
+	
+	TestSetAudioFormat();
+	TestSetBufferConfig(0);							// Without guard pages.
+	TestSetBufferConfig(KScFlagUseGuardPages);		// With guard pages.
+	TestPlay();
+	TestRecord();
+#ifdef _DEBUG		
+	TestChangeOfHwConfigNotifier();
+#endif			
+	// Note that API testing of pause/resume and volume setting are covered in T_SOUND2.
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUND_API-226
+	@SYMTestCaseDesc 		Closing the channel
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	With a playback channel open on the device, close the channel. 
+							2)	With a record channel open on the device, close the channel. 
+	@SYMTestExpectedResults	1)	No errors occur closing the channel.
+							2)	No errors occur closing the channel.
+	@SYMREQ					PREQ1073.4 */
+	
+	Test.Next(_L("Close channels"));
+	RxSoundDevice.Close();
+	TxSoundDevice.Close();
+	
+	//__KHEAP_MARKEND;
+
+	// Now that both the channels are closed, unload the LDD and the PDDs.
+	TestUnloadDrivers();
+
+	Test.End();
+	Test.Close();
+
+	Cleanup();
+	
+	__UHEAP_MARKEND;
+
+	return(KErrNone);
+	}