|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-15FDDEED-89F1-5BE5-97AD-8DFD3640369A" xml:lang="en"><title>Playback |
|
13 operation</title><shortdesc>Describes the operation of the Sound Driver for sound playback. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <section id="GUID-AECB2CE7-CB57-4AB2-B030-62E0A65851C9"><title>Normal operation</title> <p>The client calls <xref href="GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3.dita#GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3/GUID-DA119B93-6E4D-36DA-878A-D6709039E0EA"><apiname>RSoundSc::PlayData()</apiname></xref> to |
|
15 issue an audio request. </p> <p>The LDD breaks the audio request into manageable |
|
16 fragments and transfers them to the PDD by calling <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref>. </p> <p>When |
|
17 the PDD has transmitted the fragment it calls <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-16853E0D-60E8-3BEC-9E3E-9563BA7CAECE"><apiname>DSoundScLdd::PlayCallback()</apiname></xref> to |
|
18 signal to the LDD that it has finished transfer of a fragment. When the client |
|
19 request has been completed, the LDD calls <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-FDBEFD98-EE11-3358-869C-DECC3B5CF83A"><apiname>DSoundScPdd::StopTransfer()</apiname></xref> to |
|
20 stop the PDD transmitting data and to release any transfer specific resources. </p> <p>To |
|
21 ensure uninterrupted playback, a client must have multiple play requests pending |
|
22 on the driver. As soon as one request completes, the client issues a further |
|
23 request until the end of the track. Typically, a client issues a series of |
|
24 calls to <xref href="GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3.dita#GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3/GUID-DA119B93-6E4D-36DA-878A-D6709039E0EA"><apiname>RSoundSc::PlayData()</apiname></xref> to play an audio track. </p> <p>Each <xref href="GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3.dita#GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3/GUID-DA119B93-6E4D-36DA-878A-D6709039E0EA"><apiname>RSoundSc::PlayData()</apiname></xref> request |
|
25 is handled in the context of the driver's Deferred Function Call (DFC) thread. |
|
26 Assuming that the driver is not already in the process of playing data when |
|
27 the first request is received, the LDD checks whether the client has specified |
|
28 or supplied a <xref href="GUID-51514A4B-0220-557B-9F7A-FB110CEFEF10.dita">shared |
|
29 chunk</xref> to the <xref href="GUID-E2641957-8163-5EF4-B282-FC3FD9CA75A6.dita#GUID-E2641957-8163-5EF4-B282-FC3FD9CA75A6/GUID-4D6A01FE-47E7-5A6F-9DFE-F612B880165B">Driver |
|
30 channel</xref> and also whether the audio configuration and volume have both |
|
31 been set. If the chunk configuration has not been specified, then the driver |
|
32 cannot proceed and returns <codeph>KErrNotReady</codeph>. However, if the |
|
33 audio configuration or volume has not been specified, then the LDD simply |
|
34 applies default settings to the audio hardware device. These values are returned |
|
35 by the PDD functions <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-39AA2B2D-E98B-33A0-9C46-08B783413860"><apiname>DSoundScPdd::SetConfig()</apiname></xref> and <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-D893A29B-1A4B-35AF-876B-84D74B7E783C"><apiname>DSoundScPdd::SetVolume()</apiname></xref> when |
|
36 called by the LDD. </p> <p>The LDD may need to break the play request down |
|
37 into fragments to support the maximum amount of data that the PDD can handle |
|
38 in a single transfer. The function <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-534D46F4-2CB1-3130-9E72-A1C3BF085865"><apiname>DSoundScPdd::MaxTransferLen()</apiname></xref> returns |
|
39 this maximum value. The LDD queues as many transfer fragments on the PDD as |
|
40 it can accept with a call to <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref> for |
|
41 each fragment. </p> <p>To support uninterrupted transfer of audio data, the |
|
42 PDD must be able to accept at least two transfer fragments simultaneously: |
|
43 the first being actively transferred by the audio hardware device, the other |
|
44 being queued for transfer on the same device. Therefore, as long as the LDD |
|
45 has transfer fragments still to queue, it continues to call <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref> on |
|
46 the PDD until this signals that it has temporarily reached its capacity, by |
|
47 returning <codeph>KErrNotReady</codeph>. </p> <p>If the PDD accepts all the |
|
48 fragments for this initial play request then the LDD moves on to process the |
|
49 subsequent requests from the client. These are also fragmented until either |
|
50 the PDD reaches its capacity or all pending play requests are queued. </p> <p>Each |
|
51 time the PDD completes the transfer of a fragment from a play buffer, it must |
|
52 signal this event back to the LDD by calling the function <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-16853E0D-60E8-3BEC-9E3E-9563BA7CAECE"><apiname>DSoundScLdd::PlayCallback()</apiname></xref>. |
|
53 This must always be called in the context of the driver DFC thread so there |
|
54 are no synchronisation problems. For example, where transfer completion interrupts |
|
55 the processing of new play requests from the client. </p> <p>In executing <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-16853E0D-60E8-3BEC-9E3E-9563BA7CAECE"><apiname>DSoundScLdd::PlayCallback()</apiname></xref>, |
|
56 the LDD checks whether the entire transfer for the current request is now |
|
57 complete. If so, it signals completion back to the client. Also within the <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-16853E0D-60E8-3BEC-9E3E-9563BA7CAECE"><apiname>DSoundScLdd::PlayCallback()</apiname></xref> function, |
|
58 the LDD will attempt to queue further fragments on the PDD, by calling <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref>, |
|
59 as the PDD should now have the capability to accept more transfers. The PDD |
|
60 must be written to handle calls to <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref> within |
|
61 its callback to <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-8440330E-E7B1-3B43-B3C9-2290E24241E3"><apiname>DSoundScLdd::PlayCallBack()</apiname></xref>. </p> <p>If, |
|
62 on completing a request from the client, the LDD discovers that there are |
|
63 no further play requests pending from the client, then this is treated as |
|
64 an underflow situation and <codeph>KErrUnderflow</codeph> is returned to the |
|
65 client. If however, the client specified <codeph>KSndFlagLastSample</codeph> as |
|
66 the <codeph>aFlag</codeph> argument of the <xref href="GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3.dita#GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3/GUID-DA119B93-6E4D-36DA-878A-D6709039E0EA"><apiname>RSoundSc::PlayData()</apiname></xref> function |
|
67 then an underflow is expected after this request completes. </p> <p>When the |
|
68 audio request has been completed the LDD calls <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-FDBEFD98-EE11-3358-869C-DECC3B5CF83A"><apiname>DSoundScPdd::StopTransfer()</apiname></xref> on |
|
69 the PDD. This allows the PDD to release any resources necessary for transfer. </p> </section> |
|
70 <section id="GUID-E0C18DE6-E5FD-48D2-87A2-4E4C15C10BC0"><title>Pausing and resuming audio playback</title> <p>The client |
|
71 may temporarily halt the progress of audio playback at any time by issuing <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-D912620F-9C51-3AFC-8A59-31AF9455AC4A"><apiname>DSoundScLdd::Pause()</apiname></xref>. |
|
72 In order to configure the audio hardware device to halt playback, the LDD |
|
73 calls <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-0608766F-2645-3E28-B804-BD4B953DB5FF"><apiname>DSoundScPdd::PauseTransfer()</apiname></xref> on the PDD. Ideally, |
|
74 playback should be suspended in such a way that it can be resumed later, starting |
|
75 from <i>next</i> sample following the one last played. </p> <p>The client |
|
76 requests resumption of playback by calling <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-86BF7277-0CDE-3DCE-8157-DCCD8E8D60F0"><apiname>DSoundScLdd::Resume()</apiname></xref> on |
|
77 the LDD. The LDD, in turn tells the PDD to re-commence playback by calling <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-C692BF61-FA3D-3B85-BCC6-1248C9C7D9BF"><apiname>DSoundScPdd::ResumeTransfer()</apiname></xref> </p> <p>Since |
|
78 access to the hardware is required in both cases, pause and resume are handled |
|
79 in the context of the driver DFC thread. </p> </section> |
|
80 <section id="GUID-A65EF976-2523-4CE0-BDE6-1F6AF8B5DDC4"><title>Error handling during playback</title> <p>If the PDD reports |
|
81 an error when setting up the audio device for playback then the LDD immediately |
|
82 completes the first play request back to the client returning the error value |
|
83 as the result. For example, if the PDD returns a value other than <codeph>KErrNone</codeph> from |
|
84 a call to the function <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-54D3CC19-0C00-3FFA-BD1A-62618D36EB20"><apiname>DSoundScPdd::StartTransfer()</apiname></xref>. The |
|
85 LDD attempts to re-start playback data transfer when it processes any further |
|
86 play requests from the client. </p> <p>If the PDD reports an error when commencing |
|
87 transfer or as the result of the transfer of a playback fragment, then the |
|
88 LDD ceases transfer of the associated request and instead immediately completes |
|
89 the request back to the client returning the error value as the result. </p> <p>Unexpected |
|
90 errors from the PDD are returned to the LDD via the functions <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref> and <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-16853E0D-60E8-3BEC-9E3E-9563BA7CAECE"><apiname>DSoundScLdd::PlayCallback()</apiname></xref>. The <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-8C79D09B-317A-3D8E-B9C2-474812F17529"><apiname>DSoundScPdd::TransferData()</apiname></xref> function signals that |
|
91 an error has occurred when setting up the transfer of a playback fragment |
|
92 by returning an error value other than <codeph>KErrNone</codeph> or <codeph>KErrNotReady</codeph>. |
|
93 The <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-16853E0D-60E8-3BEC-9E3E-9563BA7CAECE"><apiname>DSoundScLdd::PlayCallback()</apiname></xref> function called by the |
|
94 PDD at the end of a transfer, signals an error to the LDD if the value passed |
|
95 is not equal to <codeph>KErrNone</codeph>. </p> <p>The LDD does not cancel |
|
96 the transfer of other fragments for the same request which are already queued |
|
97 on the PDD, but it ignores their outcome. However, the LDD does try to carry |
|
98 on with the transfer of subsequent play requests queued by the client. </p> <p>In |
|
99 any of the above situations, the client may choose to terminate playback operation |
|
100 by cancelling all outstanding play requests when it detects a playback error. </p> </section> |
|
101 </conbody></concept> |