|
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 } |