|
1 // Copyright (c) 2007-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 "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 // |
|
15 |
|
16 #include "mdasoundadapter.h" |
|
17 #include "mdasoundadapterbody.h" |
|
18 #include <e32debug.h> |
|
19 |
|
20 RMdaDevSound::RMdaDevSound() |
|
21 :iBody(NULL) |
|
22 { |
|
23 } |
|
24 |
|
25 /* |
|
26 @capability MultimediaDD |
|
27 |
|
28 This function creates the handle to the sound media driver. |
|
29 |
|
30 @param aUnit A unit of the device. |
|
31 |
|
32 @return KErrNone on success, otherwise system wide error code. |
|
33 |
|
34 @capability MultimediaDD |
|
35 */ |
|
36 TInt RMdaDevSound::Open(TInt aUnit) |
|
37 { |
|
38 TInt err = KErrNone; |
|
39 if(iBody == NULL) |
|
40 { |
|
41 TRAP(err, iBody = RMdaDevSound::CBody::NewL()); |
|
42 } |
|
43 if(err == KErrNone) |
|
44 { |
|
45 err = iBody->Open(aUnit); |
|
46 } |
|
47 return err; |
|
48 } |
|
49 |
|
50 /* |
|
51 Gets the version object of sound media driver. |
|
52 |
|
53 @return version object. |
|
54 |
|
55 */ |
|
56 TVersion RMdaDevSound::VersionRequired() const |
|
57 { |
|
58 if(iBody) |
|
59 { |
|
60 return iBody->VersionRequired(); |
|
61 } |
|
62 return TVersion(); |
|
63 } |
|
64 |
|
65 /* |
|
66 Indicates whether the driver is sound media driver. |
|
67 |
|
68 @return KErrNone on success, otherwise System wide error code. |
|
69 |
|
70 */ |
|
71 TInt RMdaDevSound::IsMdaSound() |
|
72 { |
|
73 return iBody->IsMdaSound(); |
|
74 } |
|
75 |
|
76 /* |
|
77 This function gets the play volume. |
|
78 The range of volume level supported depends on the physical audio device used. |
|
79 |
|
80 @return Volume level. |
|
81 |
|
82 */ |
|
83 TInt RMdaDevSound::PlayVolume() |
|
84 { |
|
85 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
86 return iBody->PlayVolume(); |
|
87 } |
|
88 |
|
89 /* |
|
90 This function sets the play volume. |
|
91 The volume level depends on the physical audio device used. |
|
92 |
|
93 @param aVolume Play volume level in the range 0 to 255 inclusive |
|
94 @see TSoundFormatsSupported |
|
95 |
|
96 */ |
|
97 void RMdaDevSound::SetPlayVolume(TInt aVolume) |
|
98 { |
|
99 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
100 iBody->SetPlayVolume(aVolume); |
|
101 } |
|
102 |
|
103 /* |
|
104 This function sets the play volume. |
|
105 The volume level depends on the physical audio device used. |
|
106 |
|
107 @param aVolume Play volume level. Logarithmic value. |
|
108 @see TSoundFormatsSupported |
|
109 |
|
110 */ |
|
111 void RMdaDevSound::SetVolume(TInt aLogarithmicVolume) |
|
112 { |
|
113 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
114 iBody->SetVolume(aLogarithmicVolume); |
|
115 } |
|
116 |
|
117 /* |
|
118 This function cancels the currently playing sound. |
|
119 If paused, the pause will be cancelled. |
|
120 Will panic if not open. |
|
121 Will not cancel Notify*Error(). |
|
122 */ |
|
123 void RMdaDevSound::CancelPlayData() |
|
124 { |
|
125 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
126 iBody->CancelPlayData(); |
|
127 } |
|
128 |
|
129 /* |
|
130 Gets the sound record volume. |
|
131 This depends on the physical audio device used. |
|
132 @return Record volume level. |
|
133 |
|
134 */ |
|
135 TInt RMdaDevSound::RecordLevel() |
|
136 { |
|
137 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
138 return iBody->RecordLevel(); |
|
139 } |
|
140 |
|
141 /* |
|
142 This function sets the device record volume level. |
|
143 This depends on the physical audio device used. |
|
144 @param aLevel Record volume level. |
|
145 @see TSoundFormatsSupported |
|
146 |
|
147 */ |
|
148 void RMdaDevSound::SetRecordLevel(TInt aLevel) |
|
149 { |
|
150 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
151 iBody->SetRecordLevel(aLevel); |
|
152 } |
|
153 |
|
154 /* |
|
155 This function cancels the recording in progress. |
|
156 If paused, the pause will be cancelled. |
|
157 Any buffered data will be discarded. |
|
158 Will panic if not open. |
|
159 Will not cancel Notify*Error(). |
|
160 */ |
|
161 void RMdaDevSound::CancelRecordData() |
|
162 { |
|
163 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
164 iBody->CancelRecordData(); |
|
165 } |
|
166 |
|
167 /* |
|
168 This function stops recording and completes the outstanding RecordData request immediately with any available data. |
|
169 Any following RecordData calls will be completed immediately returning any buffered data, they will NOT restart recording. |
|
170 |
|
171 It maybe called either when recording or stopped. |
|
172 |
|
173 The flushing state should be exited by calling CancelRecordData. |
|
174 |
|
175 The adaptor implements this functionality via Pause, which results in slightly different behaviour to the old RMdaDevSound driver. |
|
176 In particular the flushing state can also be exited by calling ResumeRecording, do NOT do this... If you want this behaviour, use the |
|
177 new PauseRecording/ResumeRecording functions. |
|
178 */ |
|
179 void RMdaDevSound::FlushRecordBuffer() |
|
180 { |
|
181 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
182 iBody->FlushRecordBuffer(); |
|
183 } |
|
184 |
|
185 /* |
|
186 This function returns the number of bytes played by the driver since calling Open or |
|
187 calling ResetBytesPlayed(). |
|
188 |
|
189 It is not reset by PlayData or PausePlayBuffer/ResumePlayBuffer |
|
190 |
|
191 @see RMdaDevSound::ResetBytesPlayed() |
|
192 @return Number of bytes played. |
|
193 */ |
|
194 TInt RMdaDevSound::BytesPlayed() |
|
195 { |
|
196 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
197 return iBody->BytesPlayed(); |
|
198 } |
|
199 |
|
200 /* |
|
201 Resets the count of bytes played. |
|
202 |
|
203 If called whilst playing, the counter might not reset to exactly zero, it will reset to the number of bytes played in the current |
|
204 internal transfer. |
|
205 */ |
|
206 void RMdaDevSound::ResetBytesPlayed() |
|
207 { |
|
208 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
209 return iBody->ResetBytesPlayed(); |
|
210 } |
|
211 |
|
212 /* |
|
213 This function changes the audio play state to pause. |
|
214 It is legal to pause whilst not playing, in which case a following (single) PlayData request will be queued until |
|
215 ResumePlaying is called. |
|
216 Currently "pause whilst not playing" is disabled due to an issue in the datapath code which panics... |
|
217 */ |
|
218 void RMdaDevSound::PausePlayBuffer() |
|
219 { |
|
220 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
221 iBody->PausePlayBuffer(); |
|
222 } |
|
223 |
|
224 |
|
225 /* |
|
226 This function starts the audio play from pause state. |
|
227 If a PlaData request was active when the Pause was requested it will continue. |
|
228 If a PlayData request was not active when the Pause was requested, but a one was issued whilst paused, |
|
229 it will start. |
|
230 If there is nothing to resume, we will notify KErrUnderflow. |
|
231 */ |
|
232 void RMdaDevSound::ResumePlaying() |
|
233 { |
|
234 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
235 iBody->ResumePlaying(); |
|
236 } |
|
237 |
|
238 /* |
|
239 This function is identical to RMdaDevSound::ResumePlaying(), the parameter is ignored. |
|
240 */ |
|
241 void RMdaDevSound::ResumePlaying(TRequestStatus&) |
|
242 { |
|
243 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
244 iBody->ResumePlaying(); |
|
245 } |
|
246 |
|
247 /* |
|
248 The current record request will be completed early with partial contents and further |
|
249 recording paused. |
|
250 |
|
251 Any following RecordData calls will be completed immediately using any buffered data, it will NOT restart recording. |
|
252 |
|
253 Pausing whilst stopped does nothing, and hence a following RecordData call would restart recording... |
|
254 |
|
255 */ |
|
256 void RMdaDevSound::PauseRecordBuffer() |
|
257 { |
|
258 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
259 iBody->PauseRecordBuffer(); |
|
260 } |
|
261 |
|
262 /* |
|
263 Resume recording. |
|
264 Recorded data will be buffered internally. |
|
265 If an outstanding RecordData request was issued whilst paused it will be processed. |
|
266 */ |
|
267 void RMdaDevSound::ResumeRecording() |
|
268 { |
|
269 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
270 iBody->ResumeRecording(); |
|
271 } |
|
272 |
|
273 /* |
|
274 Return the duration of the audio data which has been played. |
|
275 Note that this may be less than the amount of data/time queued. |
|
276 */ |
|
277 TInt RMdaDevSound::GetTimePlayed(TTimeIntervalMicroSeconds& aTimePlayed) |
|
278 { |
|
279 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
280 return iBody->GetTimePlayed(aTimePlayed); |
|
281 } |
|
282 |
|
283 |
|
284 /* |
|
285 Gets the play format(capability) supported by this device. |
|
286 This record describes supported sample rate, encoding, volume level, channels, buffer size of the audio for playing. |
|
287 |
|
288 @param aFormatsSupported A reference to a client supplied TSoundFormatsSupported class to be filled by this function. |
|
289 @see TSoundFormatsSupported |
|
290 |
|
291 */ |
|
292 void RMdaDevSound::PlayFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported) |
|
293 { |
|
294 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
295 iBody->PlayFormatsSupported(aFormatsSupported); |
|
296 } |
|
297 |
|
298 /* |
|
299 This function gets the current play format. |
|
300 |
|
301 @param aFormat A reference to a client supplied TCurrentSoundFormat class to be filled by this function. |
|
302 @see TCurrentSoundFormat |
|
303 |
|
304 */ |
|
305 void RMdaDevSound::GetPlayFormat(TCurrentSoundFormatBuf& aFormat) |
|
306 { |
|
307 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
308 iBody->GetPlayFormat(aFormat); |
|
309 } |
|
310 |
|
311 /* |
|
312 This functions sets the play format. |
|
313 |
|
314 @param aFormat For the details refer to TCurrentSoundFormat. |
|
315 |
|
316 @see TCurrentSoundFormat |
|
317 |
|
318 @return KErrNone on success, |
|
319 KErrInUse if playing, |
|
320 KErrAccessDenied if play and recording sample rate is different, |
|
321 KErrNotSupported if input sound format does not match with supported capability, |
|
322 otherwise system wide error code. |
|
323 |
|
324 */ |
|
325 TInt RMdaDevSound::SetPlayFormat(const TCurrentSoundFormatBuf& aFormat) |
|
326 { |
|
327 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
328 return iBody->SetPlayFormat(aFormat); |
|
329 } |
|
330 |
|
331 /* |
|
332 Gets the sound record format. |
|
333 This record describes supported sample rate, encoding, volume level, buffer size of the audio for recording. |
|
334 This depends on the physical device used. |
|
335 |
|
336 @param aFormatsSupported A reference to a client supplied TSoundFormatsSupported class to be filled by this function. |
|
337 @see TSoundFormatsSupported |
|
338 |
|
339 */ |
|
340 void RMdaDevSound::RecordFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported) |
|
341 { |
|
342 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
343 iBody->RecordFormatsSupported(aFormatsSupported); |
|
344 } |
|
345 |
|
346 /* |
|
347 Gets a current sound format used for recording. |
|
348 |
|
349 @param aFormat A reference to a client supplied TCurrentSoundFormat class to be filled by this function. |
|
350 @see TCurrentSoundFormat |
|
351 |
|
352 */ |
|
353 void RMdaDevSound::GetRecordFormat(TCurrentSoundFormatBuf& aFormat) |
|
354 { |
|
355 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
356 iBody->GetRecordFormat(aFormat); |
|
357 } |
|
358 |
|
359 /* |
|
360 Call this function to change the sound format used for recording. |
|
361 |
|
362 @param aFormat For details refer to TCurrentSoundFormat. |
|
363 @see TCurrentSoundFormat |
|
364 |
|
365 @return KErrNone on sucess, |
|
366 KErrInUse if recording already in progress, |
|
367 KErrAccessDenied play and record sample rates are different, |
|
368 otherwise system wide error code. |
|
369 |
|
370 */ |
|
371 TInt RMdaDevSound::SetRecordFormat(const TCurrentSoundFormatBuf& aFormat) |
|
372 { |
|
373 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
374 return iBody->SetRecordFormat(aFormat); |
|
375 } |
|
376 |
|
377 void RMdaDevSound::Close() |
|
378 { |
|
379 if(iBody) |
|
380 { |
|
381 iBody->Close(); |
|
382 delete iBody; |
|
383 iBody = NULL; |
|
384 } |
|
385 } |
|
386 |
|
387 TInt RMdaDevSound::Handle() |
|
388 { |
|
389 if(iBody) |
|
390 { |
|
391 return iBody->Handle(); |
|
392 } |
|
393 return 0; |
|
394 } |
|
395 |
|
396 /* |
|
397 Call this function to play the audio data in the supplied descriptor. |
|
398 |
|
399 Only a single request may be outstanding at any point in time. |
|
400 |
|
401 If paused, the request will be queued until ResumePlaying is called. |
|
402 |
|
403 @param aStatus For details refer to TRequestStatus. |
|
404 @see TRequestStatus |
|
405 |
|
406 @param aData Descriptor with play data |
|
407 |
|
408 */ |
|
409 void RMdaDevSound::PlayData(TRequestStatus& aStatus, const TDesC8& aData) |
|
410 { |
|
411 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
412 iBody->PlayData(aStatus, aData); |
|
413 } |
|
414 |
|
415 /* |
|
416 Records audio data into the supplied descriptor. |
|
417 |
|
418 Only a single request may be outstanding at any point in time. |
|
419 |
|
420 If paused, the request will be queued until ResumeRecording is called. |
|
421 |
|
422 @param aStatus Request status |
|
423 @see TRequestStatus |
|
424 |
|
425 @param aData Record buffer descriptor. |
|
426 |
|
427 */ |
|
428 void RMdaDevSound::RecordData(TRequestStatus& aStatus, TDes8& aData) |
|
429 { |
|
430 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
431 iBody->RecordData(aStatus, aData); |
|
432 } |
|
433 |
|
434 /* |
|
435 Call this function to notify any error encountered while recording audio. |
|
436 |
|
437 @param aStatus request object's completion code value |
|
438 @see TRequestStatus |
|
439 |
|
440 */ |
|
441 void RMdaDevSound::NotifyRecordError(TRequestStatus& aStatus) |
|
442 { |
|
443 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
444 iBody->NotifyRecordError(aStatus); |
|
445 } |
|
446 |
|
447 /* |
|
448 Call this function to notify the play error encountered while playing the sound. |
|
449 |
|
450 @param aStatus Error code stating the cause for the play error. |
|
451 |
|
452 */ |
|
453 void RMdaDevSound::NotifyPlayError(TRequestStatus& aStatus) |
|
454 { |
|
455 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
456 iBody->NotifyPlayError(aStatus); |
|
457 } |
|
458 |
|
459 /* |
|
460 This function cancels the play notification error. |
|
461 |
|
462 */ |
|
463 void RMdaDevSound::CancelNotifyPlayError() |
|
464 { |
|
465 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
466 iBody->CancelNotifyPlayError(); |
|
467 } |
|
468 |
|
469 /* |
|
470 This function cancels the recording error notification. |
|
471 */ |
|
472 void RMdaDevSound::CancelNotifyRecordError() |
|
473 { |
|
474 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
475 iBody->CancelNotifyRecordError(); |
|
476 } |
|
477 |
|
478 /* |
|
479 This function cancels the currently playing sound. |
|
480 If paused, the pause will be cancelled. |
|
481 |
|
482 This function is identical to CancelPlayData |
|
483 */ |
|
484 void RMdaDevSound::FlushPlayBuffer() |
|
485 { |
|
486 __ASSERT_DEBUG(iBody != NULL, Panic(EDeviceNotOpened)); |
|
487 iBody->FlushPlayBuffer(); |
|
488 } |