kerneltest/e32test/multimedia/t_soundmchan.cpp
changeset 9 96e5fb8b040d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/multimedia/t_soundmchan.cpp	Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,289 @@
+// 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_soundmchan.cpp
+// 
+//
+
+/**
+ @file Testing access to the shared chunk sound driver from multiple user side threads.
+*/
+
+#include <e32test.h>
+#include <e32def.h>
+#include <e32def_private.h>
+#include "t_soundutils.h"
+
+RTest Test(_L("T_SOUNDMCHAN"));
+
+const TInt KHeapSize=0x4000;
+
+enum TSecThreadTestId
+	{
+	ESecThreadConfigPlayback,
+    ESecThreadConfigRecord,
+	};	
+struct SSecondaryThreadInfo
+	{
+	TSecThreadTestId iTestId;
+//	TInt iExpectedRetVal;
+	TThreadId iThreadId;
+	TInt iDrvHandle;
+	};
+
+_LIT(KSndLddFileName,"ESOUNDSC.LDD");
+_LIT(KSndPddFileName,"SOUNDSC.PDD");
+
+
+LOCAL_C TInt secondaryThread(TAny* aTestInfo)
+	{
+	RTest stest(_L("Secondary test thread"));
+	stest.Title();
+	
+	stest.Start(_L("Check which test to perform"));
+	SSecondaryThreadInfo& sti=*((SSecondaryThreadInfo*)aTestInfo);
+	TInt r;
+	switch(sti.iTestId)
+		{
+		case ESecThreadConfigPlayback:
+			{
+			stest.Next(_L("Duplicate the channel handle passed from main thread"));
+			
+			// Get a reference to the main thread - which created the handle
+			RThread thread;
+			r=thread.Open(sti.iThreadId);
+			stest(r==KErrNone);
+	
+			// Duplicate the driver handle passed from the other thread - for this thread
+			RSoundSc snddev;
+			snddev.SetHandle(sti.iDrvHandle);
+			r=snddev.Duplicate(thread);
+			stest(r==KErrNone);
+			thread.Close();
+			
+			stest.Next(_L("Configure the driver"));
+			// Read the capabilties of this device.
+			TSoundFormatsSupportedV02Buf capsBuf;
+			snddev.Caps(capsBuf);
+			TSoundFormatsSupportedV02& caps=capsBuf();
+			
+			// Read back the default configuration - which must be valid.
+			TCurrentSoundFormatV02Buf formatBuf;
+			snddev.AudioFormat(formatBuf);
+			TCurrentSoundFormatV02& format=formatBuf();
+			
+			if (caps.iEncodings&KSoundEncoding16BitPCM)
+				format.iEncoding = ESoundEncoding16BitPCM;
+			if (caps.iRates&KSoundRate16000Hz)
+				format.iRate = ESoundRate16000Hz;
+			if (caps.iChannels&KSoundStereoChannel)
+				format.iChannels = 2;
+			r=snddev.SetAudioFormat(formatBuf);
+			stest(r==KErrNone);
+			r=snddev.SetVolume(KSoundMaxVolume);
+			stest(r==KErrNone);
+			
+			stest.Next(_L("Close the channel again"));
+			snddev.Close();
+			
+			break;	
+			}
+			
+		case ESecThreadConfigRecord:
+			{
+			stest.Next(_L("Use the channel passed from main thread to configure driver"));
+			
+			break;		
+			}
+			
+		default:
+			break;
+		}
+	
+//	stest.Getch();	
+	stest.End();
+	return(KErrNone);	
+	}
+	
+GLDEF_C TInt E32Main()
+
+    {
+	__UHEAP_MARK;
+
+	Test.Title();
+
+	TInt r;
+	Test.Start(_L("Load sound PDD"));
+	r=User::LoadPhysicalDevice(KSndPddFileName);
+	if (r==KErrNotFound)
+		{
+		Test.Printf(_L("Shared chunk sound driver not supported - test skipped\r\n"));
+		Test.End();
+		Test.Close();
+		__UHEAP_MARKEND;
+		return(KErrNone);
+		}
+	Test(r==KErrNone || r==KErrAlreadyExists);
+	
+	Test.Next(_L("Load sound LDD"));
+	r=User::LoadLogicalDevice(KSndLddFileName);
+	Test(r==KErrNone || r==KErrAlreadyExists);
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUNDMCHAN-224
+	@SYMTestCaseDesc 		Opening the channel - more than one channel
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	With the LDD and PDD installed and with all channels closed on the device, 
+								open a channel for playback on the device. 
+							2)	Without closing the first playback channel, attempt to open a second channel 
+								for playback on the same device. 
+	@SYMTestExpectedResults	1)	KErrNone - Channel opens successfully. 
+							2)	Should fail with KErrInUse.
+	@SYMREQ					PREQ1073.4 */	
+	
+	__KHEAP_MARK;
+
+	Test.Next(_L("Open a channel on the play device"));
+	RSoundSc snddev;
+	r=snddev.Open(KSoundScTxUnit0);
+	Test(r==KErrNone);
+	
+	Test.Next(_L("Try opening the same unit a second time."));
+	RSoundSc snddev2;
+	r=snddev2.Open(KSoundScTxUnit0);
+	Test(r==KErrInUse);
+	
+	Test.Next(_L("Query play formats supported"));
+	TSoundFormatsSupportedV02Buf capsBuf;
+	snddev.Caps(capsBuf);
+	TSoundFormatsSupportedV02& caps=capsBuf();
+	PrintCaps(caps,Test);
+	
+	Test.Next(_L("Try playing without setting the buffer config"));
+	TRequestStatus pStat;
+	snddev.PlayData(pStat,0,0x2000);	// 8K
+	User::WaitForRequest(pStat);
+	Test(pStat.Int()==KErrNotReady);
+
+	Test.Next(_L("Configure the channel from a 2nd thread"));
+	RThread thread;
+	TRequestStatus tStat;
+	SSecondaryThreadInfo sti;
+	
+	sti.iTestId=ESecThreadConfigPlayback;
+	sti.iThreadId=RThread().Id();	// Get the ID of this thread
+	sti.iDrvHandle=snddev.Handle();	// Pass the channel handle
+	
+	/**	@SYMTestCaseID 		PBASE-T_SOUNDMCHAN-225
+	@SYMTestCaseDesc 		Opening the channel - sharing the handle between threads
+	@SYMTestPriority 		Critical
+	@SYMTestActions			1)	With the LDD and PDD installed and with all channels closed on the device, open a 
+								channel for playback on the device. Now create a second thread. Resume this 
+								thread - passing the handle to the playback channel to it. Wait for the second 
+								thread to terminate.
+							2)	In the second thread, duplicate the playback channel handle.
+							3)	In the second thread, using the duplicated handle, issue a request to set the audio configuration. 
+							4)	In the second thread, using the duplicated handle, issue a request to set the volume. 
+							5)	In the second thread, close the handle and exit the thread.
+							6)	In the first thread, read back the audio configuration.
+							7)	In the first thread, set the buffer configuration, and then issue a request to play 
+								audio data. 
+							8)	In the first thread, close the channel. 
+	@SYMTestExpectedResults	1)	KErrNone - Channel opens successfully. 
+							2)	KErrNone - Duplication of the handle succeeds.
+							3)	KErrNone - Audio configured successfully.
+							4)	KErrNone - Volume set successfully.
+							5)	No errors occur closing the channel and exiting the thread.
+							6)	The audio configuration should correspond to that set by the second thread.
+							7)	KErrNone - Setting the buffer configuration and issuing a play request.
+							8)	No errors occur closing the channel.
+	@SYMREQ					PREQ1073.4 */	
+	
+	r=thread.Create(_L("Thread"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); // Create secondary thread
+	Test(r==KErrNone);
+	thread.Logon(tStat);
+	thread.Resume();
+	User::WaitForRequest(tStat);
+	Test(tStat.Int()==KErrNone);
+//	Test.Printf(_L("Thread exit info: Cat:%S, Reason:%x, Type:%d\r\n"),&thread.ExitCategory(),thread.ExitReason(),thread.ExitType());
+	Test(thread.ExitType()==EExitKill);
+	thread.Close();
+	User::After(10000);	// Wait 10ms
+	
+	Test.Next(_L("Read back the play configuration"));
+	TCurrentSoundFormatV02Buf formatBuf;
+	snddev.AudioFormat(formatBuf);
+	TCurrentSoundFormatV02& format=formatBuf();
+	PrintConfig(format,Test);
+	
+	Test.Next(_L("Set the buffer configuration"));
+	RChunk chunk;
+	TInt bufSize=BytesPerSecond(formatBuf()); 	 							// Large enough to hold 1 second of data.
+	bufSize=ValidBufferSize(bufSize,caps.iRequestMinSize,formatBuf());		// Keep the buffer length valid for driver.
+	TTestSharedChunkBufConfig bufferConfig;
+	bufferConfig.iNumBuffers=1;
+	bufferConfig.iBufferSizeInBytes=bufSize;
+	bufferConfig.iFlags=0;	
+	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
+	r=snddev.SetBufferChunkCreate(bufferConfigBuf,chunk);
+	Test(r==KErrNone);
+	snddev.GetBufferConfig(bufferConfigBuf);
+	PrintBufferConf(bufferConfig,Test);
+	Test(bufferConfig.iBufferSizeInBytes==bufSize);
+	
+	Test.Next(_L("Start playing"));
+	r=MakeSineTable(format);
+	Test(r==KErrNone);
+	r=SetToneFrequency(660,format);
+	Test(r==KErrNone); 
+	TPtr8 ptr(chunk.Base()+bufferConfig.iBufferOffsetList[0],bufSize);
+	WriteTone(ptr,format);
+	snddev.PlayData(pStat,bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
+	User::WaitForRequest(pStat);
+	Test(tStat.Int()==KErrNone);
+	
+	Test.Next(_L("Close the drivers and the chunk"));
+	chunk.Close();
+	snddev.Close();
+	
+	__KHEAP_MARKEND;
+
+	Test.Next(_L("Unload the drivers"));
+	
+	r=User::FreeLogicalDevice(KDevSoundScName);
+	Test.Printf(_L("Unloading %S.LDD - %d\r\n"),&KDevSoundScName,r);
+	Test(r==KErrNone);
+	
+	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);
+		Test(r==KErrNone);
+		findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container.
+		r=findPD.Next(findResult);
+		} 
+	
+	Test.End();
+	Test.Close();
+	
+	Cleanup();
+	
+	__UHEAP_MARKEND;
+
+	return(KErrNone);
+    }