os/kernelhwsrv/kerneltest/e32test/multimedia/t_soundmchan.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\multimedia\t_soundmchan.cpp
    15 // 
    16 //
    17 
    18 /**
    19  @file Testing access to the shared chunk sound driver from multiple user side threads.
    20 */
    21 
    22 #include <e32test.h>
    23 #include <e32def.h>
    24 #include <e32def_private.h>
    25 #include "t_soundutils.h"
    26 
    27 RTest Test(_L("T_SOUNDMCHAN"));
    28 
    29 const TInt KHeapSize=0x4000;
    30 
    31 enum TSecThreadTestId
    32 	{
    33 	ESecThreadConfigPlayback,
    34     ESecThreadConfigRecord,
    35 	};	
    36 struct SSecondaryThreadInfo
    37 	{
    38 	TSecThreadTestId iTestId;
    39 //	TInt iExpectedRetVal;
    40 	TThreadId iThreadId;
    41 	TInt iDrvHandle;
    42 	};
    43 
    44 _LIT(KSndLddFileName,"ESOUNDSC.LDD");
    45 _LIT(KSndPddFileName,"SOUNDSC.PDD");
    46 
    47 
    48 LOCAL_C TInt secondaryThread(TAny* aTestInfo)
    49 	{
    50 	RTest stest(_L("Secondary test thread"));
    51 	stest.Title();
    52 	
    53 	stest.Start(_L("Check which test to perform"));
    54 	SSecondaryThreadInfo& sti=*((SSecondaryThreadInfo*)aTestInfo);
    55 	TInt r;
    56 	switch(sti.iTestId)
    57 		{
    58 		case ESecThreadConfigPlayback:
    59 			{
    60 			stest.Next(_L("Duplicate the channel handle passed from main thread"));
    61 			
    62 			// Get a reference to the main thread - which created the handle
    63 			RThread thread;
    64 			r=thread.Open(sti.iThreadId);
    65 			stest(r==KErrNone);
    66 	
    67 			// Duplicate the driver handle passed from the other thread - for this thread
    68 			RSoundSc snddev;
    69 			snddev.SetHandle(sti.iDrvHandle);
    70 			r=snddev.Duplicate(thread);
    71 			stest(r==KErrNone);
    72 			thread.Close();
    73 			
    74 			stest.Next(_L("Configure the driver"));
    75 			// Read the capabilties of this device.
    76 			TSoundFormatsSupportedV02Buf capsBuf;
    77 			snddev.Caps(capsBuf);
    78 			TSoundFormatsSupportedV02& caps=capsBuf();
    79 			
    80 			// Read back the default configuration - which must be valid.
    81 			TCurrentSoundFormatV02Buf formatBuf;
    82 			snddev.AudioFormat(formatBuf);
    83 			TCurrentSoundFormatV02& format=formatBuf();
    84 			
    85 			if (caps.iEncodings&KSoundEncoding16BitPCM)
    86 				format.iEncoding = ESoundEncoding16BitPCM;
    87 			if (caps.iRates&KSoundRate16000Hz)
    88 				format.iRate = ESoundRate16000Hz;
    89 			if (caps.iChannels&KSoundStereoChannel)
    90 				format.iChannels = 2;
    91 			r=snddev.SetAudioFormat(formatBuf);
    92 			stest(r==KErrNone);
    93 			r=snddev.SetVolume(KSoundMaxVolume);
    94 			stest(r==KErrNone);
    95 			
    96 			stest.Next(_L("Close the channel again"));
    97 			snddev.Close();
    98 			
    99 			break;	
   100 			}
   101 			
   102 		case ESecThreadConfigRecord:
   103 			{
   104 			stest.Next(_L("Use the channel passed from main thread to configure driver"));
   105 			
   106 			break;		
   107 			}
   108 			
   109 		default:
   110 			break;
   111 		}
   112 	
   113 //	stest.Getch();	
   114 	stest.End();
   115 	return(KErrNone);	
   116 	}
   117 	
   118 GLDEF_C TInt E32Main()
   119 
   120     {
   121 	__UHEAP_MARK;
   122 
   123 	Test.Title();
   124 
   125 	TInt r;
   126 	Test.Start(_L("Load sound PDD"));
   127 	r=User::LoadPhysicalDevice(KSndPddFileName);
   128 	if (r==KErrNotFound)
   129 		{
   130 		Test.Printf(_L("Shared chunk sound driver not supported - test skipped\r\n"));
   131 		Test.End();
   132 		Test.Close();
   133 		__UHEAP_MARKEND;
   134 		return(KErrNone);
   135 		}
   136 	Test(r==KErrNone || r==KErrAlreadyExists);
   137 	
   138 	Test.Next(_L("Load sound LDD"));
   139 	r=User::LoadLogicalDevice(KSndLddFileName);
   140 	Test(r==KErrNone || r==KErrAlreadyExists);
   141 	
   142 	/**	@SYMTestCaseID 		PBASE-T_SOUNDMCHAN-224
   143 	@SYMTestCaseDesc 		Opening the channel - more than one channel
   144 	@SYMTestPriority 		Critical
   145 	@SYMTestActions			1)	With the LDD and PDD installed and with all channels closed on the device, 
   146 								open a channel for playback on the device. 
   147 							2)	Without closing the first playback channel, attempt to open a second channel 
   148 								for playback on the same device. 
   149 	@SYMTestExpectedResults	1)	KErrNone - Channel opens successfully. 
   150 							2)	Should fail with KErrInUse.
   151 	@SYMREQ					PREQ1073.4 */	
   152 	
   153 	__KHEAP_MARK;
   154 
   155 	Test.Next(_L("Open a channel on the play device"));
   156 	RSoundSc snddev;
   157 	r=snddev.Open(KSoundScTxUnit0);
   158 	Test(r==KErrNone);
   159 	
   160 	Test.Next(_L("Try opening the same unit a second time."));
   161 	RSoundSc snddev2;
   162 	r=snddev2.Open(KSoundScTxUnit0);
   163 	Test(r==KErrInUse);
   164 	
   165 	Test.Next(_L("Query play formats supported"));
   166 	TSoundFormatsSupportedV02Buf capsBuf;
   167 	snddev.Caps(capsBuf);
   168 	TSoundFormatsSupportedV02& caps=capsBuf();
   169 	PrintCaps(caps,Test);
   170 	
   171 	Test.Next(_L("Try playing without setting the buffer config"));
   172 	TRequestStatus pStat;
   173 	snddev.PlayData(pStat,0,0x2000);	// 8K
   174 	User::WaitForRequest(pStat);
   175 	Test(pStat.Int()==KErrNotReady);
   176 
   177 	Test.Next(_L("Configure the channel from a 2nd thread"));
   178 	RThread thread;
   179 	TRequestStatus tStat;
   180 	SSecondaryThreadInfo sti;
   181 	
   182 	sti.iTestId=ESecThreadConfigPlayback;
   183 	sti.iThreadId=RThread().Id();	// Get the ID of this thread
   184 	sti.iDrvHandle=snddev.Handle();	// Pass the channel handle
   185 	
   186 	/**	@SYMTestCaseID 		PBASE-T_SOUNDMCHAN-225
   187 	@SYMTestCaseDesc 		Opening the channel - sharing the handle between threads
   188 	@SYMTestPriority 		Critical
   189 	@SYMTestActions			1)	With the LDD and PDD installed and with all channels closed on the device, open a 
   190 								channel for playback on the device. Now create a second thread. Resume this 
   191 								thread - passing the handle to the playback channel to it. Wait for the second 
   192 								thread to terminate.
   193 							2)	In the second thread, duplicate the playback channel handle.
   194 							3)	In the second thread, using the duplicated handle, issue a request to set the audio configuration. 
   195 							4)	In the second thread, using the duplicated handle, issue a request to set the volume. 
   196 							5)	In the second thread, close the handle and exit the thread.
   197 							6)	In the first thread, read back the audio configuration.
   198 							7)	In the first thread, set the buffer configuration, and then issue a request to play 
   199 								audio data. 
   200 							8)	In the first thread, close the channel. 
   201 	@SYMTestExpectedResults	1)	KErrNone - Channel opens successfully. 
   202 							2)	KErrNone - Duplication of the handle succeeds.
   203 							3)	KErrNone - Audio configured successfully.
   204 							4)	KErrNone - Volume set successfully.
   205 							5)	No errors occur closing the channel and exiting the thread.
   206 							6)	The audio configuration should correspond to that set by the second thread.
   207 							7)	KErrNone - Setting the buffer configuration and issuing a play request.
   208 							8)	No errors occur closing the channel.
   209 	@SYMREQ					PREQ1073.4 */	
   210 	
   211 	r=thread.Create(_L("Thread"),secondaryThread,KDefaultStackSize,KHeapSize,KHeapSize,&sti); // Create secondary thread
   212 	Test(r==KErrNone);
   213 	thread.Logon(tStat);
   214 	thread.Resume();
   215 	User::WaitForRequest(tStat);
   216 	Test(tStat.Int()==KErrNone);
   217 //	Test.Printf(_L("Thread exit info: Cat:%S, Reason:%x, Type:%d\r\n"),&thread.ExitCategory(),thread.ExitReason(),thread.ExitType());
   218 	Test(thread.ExitType()==EExitKill);
   219 	thread.Close();
   220 	User::After(10000);	// Wait 10ms
   221 	
   222 	Test.Next(_L("Read back the play configuration"));
   223 	TCurrentSoundFormatV02Buf formatBuf;
   224 	snddev.AudioFormat(formatBuf);
   225 	TCurrentSoundFormatV02& format=formatBuf();
   226 	PrintConfig(format,Test);
   227 	
   228 	Test.Next(_L("Set the buffer configuration"));
   229 	RChunk chunk;
   230 	TInt bufSize=BytesPerSecond(formatBuf()); 	 							// Large enough to hold 1 second of data.
   231 	bufSize=ValidBufferSize(bufSize,caps.iRequestMinSize,formatBuf());		// Keep the buffer length valid for driver.
   232 	TTestSharedChunkBufConfig bufferConfig;
   233 	bufferConfig.iNumBuffers=1;
   234 	bufferConfig.iBufferSizeInBytes=bufSize;
   235 	bufferConfig.iFlags=0;	
   236 	TPckg<TTestSharedChunkBufConfig> bufferConfigBuf(bufferConfig);
   237 	r=snddev.SetBufferChunkCreate(bufferConfigBuf,chunk);
   238 	Test(r==KErrNone);
   239 	snddev.GetBufferConfig(bufferConfigBuf);
   240 	PrintBufferConf(bufferConfig,Test);
   241 	Test(bufferConfig.iBufferSizeInBytes==bufSize);
   242 	
   243 	Test.Next(_L("Start playing"));
   244 	r=MakeSineTable(format);
   245 	Test(r==KErrNone);
   246 	r=SetToneFrequency(660,format);
   247 	Test(r==KErrNone); 
   248 	TPtr8 ptr(chunk.Base()+bufferConfig.iBufferOffsetList[0],bufSize);
   249 	WriteTone(ptr,format);
   250 	snddev.PlayData(pStat,bufferConfig.iBufferOffsetList[0],bufSize,KSndFlagLastSample);
   251 	User::WaitForRequest(pStat);
   252 	Test(tStat.Int()==KErrNone);
   253 	
   254 	Test.Next(_L("Close the drivers and the chunk"));
   255 	chunk.Close();
   256 	snddev.Close();
   257 	
   258 	__KHEAP_MARKEND;
   259 
   260 	Test.Next(_L("Unload the drivers"));
   261 	
   262 	r=User::FreeLogicalDevice(KDevSoundScName);
   263 	Test.Printf(_L("Unloading %S.LDD - %d\r\n"),&KDevSoundScName,r);
   264 	Test(r==KErrNone);
   265 	
   266 	TName pddName(KDevSoundScName);
   267 	_LIT(KPddWildcardExtension,".*");
   268 	pddName.Append(KPddWildcardExtension);
   269 	TFindPhysicalDevice findPD(pddName);
   270 	TFullName findResult;
   271 	r=findPD.Next(findResult);
   272 	while (r==KErrNone)
   273 		{
   274 		r=User::FreePhysicalDevice(findResult);
   275 		Test.Printf(_L("Unloading %S.PDD - %d\r\n"),&findResult,r);
   276 		Test(r==KErrNone);
   277 		findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container.
   278 		r=findPD.Next(findResult);
   279 		} 
   280 	
   281 	Test.End();
   282 	Test.Close();
   283 	
   284 	Cleanup();
   285 	
   286 	__UHEAP_MARKEND;
   287 
   288 	return(KErrNone);
   289     }