|
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-AC560324-798C-5D0A-B23D-2419A7688A5B" xml:lang="en"><title>Channel |
|
13 Implementation</title><shortdesc>Describes how to implement the physical channels with the template |
|
14 port. </shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
15 <p>A Sound Driver PDD must implement physical channels to use the audio hardware |
|
16 of the phone. The main Sound Driver PDD class is derived from <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita"><apiname>DSoundScPdd</apiname></xref>. |
|
17 A Sound Driver PDD that provides record and playback functions must implement |
|
18 a record driver channel and a playback driver channel. </p> |
|
19 <p>The template defines two classes: <codeph>DTemplateSoundScRxPdd</codeph> and <codeph>DTemplateSoundScTxPdd</codeph>, |
|
20 corresponding to record and playback respectively. The classes provide default |
|
21 implementations for the virtual functions defined by <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita"><apiname>DSoundScPdd</apiname></xref>, |
|
22 together with a constructor and destructor, and typically need little or no |
|
23 modification. </p> |
|
24 <section id="GUID-61725EEB-5114-5A85-9C28-57A47F14000C"><title>PDD class constructor</title> <p>Implement |
|
25 the PDD class constructor for both the playback and record driver channels. |
|
26 This is normally limited to </p> <ul> |
|
27 <li id="GUID-E02B0EE1-5171-5E9F-9BFE-FFAB6E15B290"><p>initialising any data |
|
28 members that need values other than zero </p> </li> |
|
29 <li id="GUID-4B39AEC4-0A02-5099-9805-F35B2AF4AD90"><p>initialising any DFC |
|
30 call-backs added. </p> </li> |
|
31 </ul> <p>Access to hardware has the potential to fail and so should be deferred |
|
32 to the second stage constructor <xref href="GUID-AC560324-798C-5D0A-B23D-2419A7688A5B.dita#GUID-AC560324-798C-5D0A-B23D-2419A7688A5B/GUID-F66BF339-FCE6-5859-87D1-7A0B0ED69D84">DoCreate()</xref>. </p> </section> |
|
33 <section id="GUID-CD12E6E9-C363-5CF9-91E1-694C34DE2BD9"><title>PDD class destructor</title> <p>Implement |
|
34 the PDD class destructor for both the playback and record driver channels. |
|
35 The destructor must release any hardware and Symbian platform resources that |
|
36 have been allocated to the driver. For example, this might include: </p> <ul> |
|
37 <li id="GUID-6D33C44B-B88F-504B-B750-FF010A72A290"><p>unbinding ISRs </p> </li> |
|
38 <li id="GUID-9DF0D93B-6782-5E94-80EB-A806BC1AB6B9"><p>cancelling private DFCs </p> </li> |
|
39 <li id="GUID-157C24A6-52F6-5BF1-BF94-035394F274F5"><p>closing DMA channels </p> </li> |
|
40 <li id="GUID-47452140-FA8E-55A8-BE2D-32AC87FF215E"><p>deleting any mono-to-stereo |
|
41 conversion buffers </p> </li> |
|
42 </ul> <p>The template versions of this function delete each DMA request object |
|
43 created in the PDD second stage constructor <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-C0CA28E4-2356-333D-B708-CBE469F1614F"><apiname>DSoundScPdd::DoCreate()</apiname></xref> and |
|
44 close the DMA channel. </p> </section> |
|
45 <section id="GUID-F66BF339-FCE6-5859-87D1-7A0B0ED69D84"><title>DoCreate()</title> <p>Implement |
|
46 a PDD class second stage constructor for both the playback and record driver |
|
47 channels. In the template version, the function <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-C0CA28E4-2356-333D-B708-CBE469F1614F"><apiname>DSoundScPdd::DoCreate()</apiname></xref> is |
|
48 called from the PDD factory when a channel is opened on the device. Generally, |
|
49 any hardware or Symbian platform resources required by the driver |
|
50 channel should be acquired here. However, powering up the sound device should |
|
51 be deferred to the <xref href="GUID-AC560324-798C-5D0A-B23D-2419A7688A5B.dita#GUID-AC560324-798C-5D0A-B23D-2419A7688A5B/GUID-B72057E6-B93C-505F-9789-83251D09B78E">PowerUp()</xref> function. |
|
52 Operations performed by this function include: </p> <ul> |
|
53 <li id="GUID-C3E2E6ED-14AE-52D1-9F11-618DCE7D2C1E"><p>binding an ISR to an |
|
54 audio related interrupt </p> </li> |
|
55 <li id="GUID-129BD014-9302-50AE-A33B-728D40DBF428"><p>open a DMA channel </p> </li> |
|
56 <li id="GUID-51B51BEC-B8B8-50CF-8618-BB0B5B00F999"><p>allocate a mono-to-stereo |
|
57 conversion buffer </p> </li> |
|
58 </ul> <p>The template versions of this function include code to set up a DMA |
|
59 channel. This involves opening a DMA channel in the appropriate direction |
|
60 for the driver channel and then allocating a set of DMA request objects. However, |
|
61 to use this implementation you must supply the missing platform specific information: </p> <ul> |
|
62 <li id="GUID-64F62CF9-9D26-5E39-A632-39DF91AB1E98"><p>Provide values for the |
|
63 maximum number of DMA requests outstanding on the DMA channel. These values |
|
64 determine the number of separate DMA request objects allocated for the DMA |
|
65 channel, and so the number of transfer fragments that the PDD can accept from |
|
66 the LDD at any time. See <xref href="GUID-15FDDEED-89F1-5BE5-97AD-8DFD3640369A.dita">playback</xref> and <xref href="GUID-4AEF7595-17C0-513E-9568-B212E6194388.dita">record</xref>. </p> </li> |
|
67 <li id="GUID-60C86EBD-B26F-501D-B7D5-CE113D4368C0"><p>Set the appropriate |
|
68 DMA values for your device within the file <filepath>soundsc_plat.h</filepath>. |
|
69 These values, renamed in section <xref href="GUID-C6ABE2CA-901E-55F1-9837-7018A1612BCF.dita">copying |
|
70 the template port implementation</xref> to reflect your device name, are <codeph>KTemplateMaxTxDmaRequests</codeph> or <codeph>KTemplateMaxRxDmaRequests</codeph> for playback and record respectively. </p> </li> |
|
71 <li id="GUID-BBF4F320-22A7-54AE-ACD1-6C10138F5031"><p>Setup the DMA channel |
|
72 information for the device. This includes the following members of <xref href="GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37.dita#GUID-83882548-FAC5-3EFF-92ED-14D1D9A85D37/GUID-6B973278-8BE7-3CE5-97D8-60E8D3F4D473"><apiname>TDmaChannel::SCreateInfo</apiname></xref>. </p> <ul> |
|
73 <li id="GUID-084CF2BA-308D-5F32-9BC2-C5B39DEC497B"><p> <codeph>iCookie</codeph>: |
|
74 The platform specific ID used by the DMA controller to select the DMA channel |
|
75 to open. </p> </li> |
|
76 <li id="GUID-7EE1F596-9FB5-5C29-8130-097CE6129F91"><p> <codeph>iDesCount</codeph>: |
|
77 The number of DMA descriptors the DMA controller should create. This is typically |
|
78 set with the same value as <codeph>KTemplateMaxTxDmaRequests</codeph> or <codeph>KTemplateMaxRxDmaRequests</codeph>. </p> </li> |
|
79 <li id="GUID-0B12DDF1-AC34-5592-AC55-E0363C60449A"><p> <codeph>iDfcQ</codeph>: |
|
80 The DFC queue to use to service DMA interrupts. This should point to the same |
|
81 DFC queue that is returned to the LDD for client request handling. See the <xref href="GUID-AC560324-798C-5D0A-B23D-2419A7688A5B.dita#GUID-AC560324-798C-5D0A-B23D-2419A7688A5B/GUID-32C77B77-76CE-54AE-B791-28A7DD309A7D">DfcQ()</xref> section. </p> </li> |
|
82 <li id="GUID-AE4E59DD-4FBB-54A8-BE79-F4138AB34D5C"><p> <codeph>iDfcPriority</codeph>: |
|
83 The DFC priority. This should be set to a higher value than that used by the |
|
84 LDD for handling client requests. For example, higher than one. </p> </li> |
|
85 </ul> </li> |
|
86 </ul> </section> |
|
87 <section id="GUID-32C77B77-76CE-54AE-B791-28A7DD309A7D"><title>DfcQ()</title> <p>Make |
|
88 sure that the template version of the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-C41B9733-BE86-3CF1-83A7-150EC9D35249"><apiname>DSoundScPdd::DfcQ()</apiname></xref> function |
|
89 is appropriate for your configuration. This function has the following signature: </p> <codeblock id="GUID-28E301B7-C032-5F6E-BCA7-A6D20FC541EA" xml:space="preserve">TDfcQue* DfcQ()</codeblock> <p>The |
|
90 supplied implementation is as follows </p> <codeblock id="GUID-D95DC9F9-C68A-50E2-ADA6-8D1268A18147" xml:space="preserve">TDfcQue* DTemplateSoundScTxPdd::DfcQ() |
|
91 { |
|
92 return(iPhysicalDevice->iDfcQPtr); |
|
93 }</codeblock> <p>Many requests are executed in the context of a kernel-side |
|
94 thread. Rather than assign a kernel thread for the driver in the LDD, the |
|
95 Sound Driver allows the PDD to specify the DFC thread returned via the <xref href="GUID-71190437-912E-3E23-8E68-4FA8FF913D7A.dita"><apiname>DfcQ()</apiname></xref> function, |
|
96 which it calls when the driver channel is opened. </p> <p>The default implementation |
|
97 for the record and playback driver channels, returns a pointer to the DFC |
|
98 queue created by the PDD factory class. </p> <p>See also <xref href="GUID-1138D29D-2EC5-59DF-9AA7-2D863FBC024F.dita">Implementing |
|
99 the PDD factory</xref> </p> </section> |
|
100 <section id="GUID-B549F062-061D-5876-AB43-AC10C62477EE"><title>GetChunkCreateInfo()</title> <p>Implement |
|
101 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-9F845935-A6AA-320B-AF09-F121F95C44B2"><apiname>DSoundScPdd::GetChunkCreateInfo()</apiname></xref> function for both |
|
102 the playback and record driver channels. This function has the following signature: </p> <codeblock id="GUID-934D39E5-5DDE-5165-BCED-255CA6D0B0F2" xml:space="preserve">void DSoundScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)</codeblock> <p>The |
|
103 supplied implementation is as follows: </p> <codeblock id="GUID-47334636-5E5D-59CF-A894-62747DD648BD" xml:space="preserve">void DTemplateSoundScTxPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) |
|
104 { |
|
105 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::GetChunkCreateInfo")); |
|
106 |
|
107 // TO DO: (mandatory) |
|
108 // Setup the shared chunk create information in aChunkCreateInfo for this play device. |
|
109 aChunkCreateInfo.iType=TChunkCreateInfo::ESharedKernelMultiple; |
|
110 // aChunkCreateInfo.iMapAttr=??? |
|
111 aChunkCreateInfo.iOwnsMemory=ETrue; // Using RAM pages. |
|
112 aChunkCreateInfo.iDestroyedDfc=NULL; // No chunk destroy DFC. |
|
113 }</codeblock> <p>The PDD must initialise the <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita"><apiname>TChunkCreateInfo</apiname></xref> object |
|
114 with the information that defines the characteristics of the shared chunk |
|
115 required for the audio device. This function is called by the LDD just before |
|
116 it creates a shared chunk for the channel, in response to an <xref href="GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3.dita#GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3/GUID-1978D84C-6E2A-39C0-AF5F-17C85E5B25B4"><apiname>RSoundSc::SetBufferChunkCreate()</apiname></xref> request |
|
117 from the client. </p> <p>Values for the following data members must be supplied |
|
118 by the PDD: </p> <ul> |
|
119 <li id="GUID-10F7ED98-299F-5D90-A7EC-85BD97BBECEF"><p> <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita#GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4/GUID-4384AF76-CECE-3B86-BE92-375C1DEA36DA"><apiname>TChunkCreateInfo::iType</apiname></xref> </p> </li> |
|
120 <li id="GUID-10159693-8680-5CD7-88C8-A967DDC53024"><p> <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita#GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4/GUID-4D355352-04CA-34D2-B1F4-684E07E7DDE9"><apiname>TChunkCreateInfo::iMapAttr</apiname></xref> </p> </li> |
|
121 <li id="GUID-06459B1A-5D5A-5013-912D-0C52E7FD398A"><p> <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita#GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4/GUID-106850A0-5498-387F-AF70-F9D04EB6318D"><apiname>TChunkCreateInfo::iOwnsMemory</apiname></xref> </p> </li> |
|
122 <li id="GUID-D8DE49EB-04D5-50BA-8CEA-7EFFA7584A74"><p> <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita#GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4/GUID-58271733-146A-3ECB-91AC-C38BD2ADC9A0"><apiname>TChunkCreateInfo::iDestroyedDfc</apiname></xref> </p> </li> |
|
123 </ul> <p>The data member <xref href="GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4.dita#GUID-51F7DBCF-BFB6-31F9-8882-5D263A1AD4B4/GUID-3BE6D452-84D0-3E80-8238-7A9114A89ED5"><apiname>TChunkCreateInfo::iMaxSize</apiname></xref> is |
|
124 calculated by the LDD so there is no need to define it. </p> <p>See <xref href="GUID-51514A4B-0220-557B-9F7A-FB110CEFEF10.dita">How to share chunks</xref>. </p> </section> |
|
125 <section id="GUID-9D4D9F06-8C88-51C1-9E29-D0B95B523A8D"><title>Caps()</title> <p>Implement |
|
126 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-B80B86C6-696A-37AA-9ACD-2BC76B88762C"><apiname>DSoundScPdd::Caps()</apiname></xref> function for both the playback |
|
127 and record driver channels. The function has the following signature: </p> <codeblock id="GUID-8306A135-350C-5F8D-B51D-F8A2EED41244" xml:space="preserve">void DSoundScPdd::Caps(TDes8& aCapsBuf) const</codeblock> <p>The |
|
128 supplied implementation is as follows: </p> <codeblock id="GUID-27BE7DD7-D42B-54BA-AC77-1201C1F09F68" xml:space="preserve">void DTemplateSoundScTxPdd::Caps(TDes8& aCapsBuf) const |
|
129 { |
|
130 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::Caps")); |
|
131 |
|
132 // Copy iCaps back. |
|
133 TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); |
|
134 aCapsBuf.FillZ(aCapsBuf.MaxLength()); |
|
135 aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); |
|
136 }</codeblock> <p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita"><apiname>TSoundFormatsSupportedV02</apiname></xref> is the |
|
137 main audio capabilities class. The PDD must fill this object with the capabilities |
|
138 for the particular audio device. the LDD uses this to get the play or record |
|
139 capabilities of a particular sound device once a driver channel to the device |
|
140 has been opened. </p> <p>Values for the following variables must be supplied |
|
141 by the PDD: </p> <ul> |
|
142 <li id="GUID-2F03F186-D9AF-5431-B3F8-D3B794352208"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-1FE2868A-1823-308A-B1C9-2DAD557F6F3A"><apiname>TSoundFormatsSupportedV02::iDirection</apiname></xref> </p> <ul> |
|
143 <li id="GUID-053B114E-2A52-53FD-912F-F8FF890601C4"><p> <xref href="GUID-AF772B74-0D5F-3270-BA61-2503BA5DFE6B.dita"><apiname>ESoundDirRecord</apiname></xref> </p> </li> |
|
144 <li id="GUID-CEADC6F1-6016-5AB1-9349-EEFB63EF26AA"><p> <xref href="GUID-708043EB-5ED5-3923-B41A-321AD7DF3D8C.dita"><apiname>ESoundDirPlayback</apiname></xref> </p> </li> |
|
145 </ul> </li> |
|
146 <li id="GUID-95FC1D2B-BBFB-52DC-ADE3-BA980E7E46F3"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-75B0E2F7-44BE-3A97-B482-E1CB29D9F2E5"><apiname>TSoundFormatsSupportedV02::iChannels</apiname></xref> </p> <ul> |
|
147 <li id="GUID-998425C3-E73B-5DB4-94F8-10BDCFBBE779"><p> <xref href="GUID-65BCF594-59A1-335F-AADB-1920E7AD3F71.dita"><apiname>KSoundMonoChannel</apiname></xref> </p> </li> |
|
148 <li id="GUID-7D5EE578-16AC-56A0-B064-6000F5A9C2DF"><p> <xref href="GUID-4E63CE9C-C604-3B2C-993D-9A0502A39064.dita"><apiname>KSoundStereoChannel</apiname></xref> </p> </li> |
|
149 <li id="GUID-0C17CB17-7452-5A1A-B76D-75A57960BDE8"><p> <xref href="GUID-30E8F803-39E1-3F53-AB5A-3B593BC1D69F.dita"><apiname>KSoundThreeChannel</apiname></xref> </p> </li> |
|
150 <li id="GUID-E1DE0CD0-DD63-5140-A5C5-7141A5E9632D"><p> <xref href="GUID-BD021640-3457-3721-9DF1-A15EE8A874AC.dita"><apiname>KSoundFourChannel</apiname></xref> </p> </li> |
|
151 <li id="GUID-E59E9D5E-F360-52FD-A0D0-C7CDAE5593DC"><p> <xref href="GUID-3E3B5485-F69B-3ECC-A0A4-12183444E61F.dita"><apiname>KSoundFiveChannel</apiname></xref> </p> </li> |
|
152 <li id="GUID-56DD5098-0C0C-5175-B375-766FE628C359"><p> <xref href="GUID-83C9F5FE-DE44-3940-B738-BD4486293C39.dita"><apiname>KSoundSixChannel</apiname></xref> </p> </li> |
|
153 </ul> </li> |
|
154 <li id="GUID-A6847CF6-48DC-510E-BCFF-33E7E5FB0161"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-1F79E9BB-BF7C-31AD-AA0C-A85748F4231A"><apiname>TSoundFormatsSupportedV02::iRates</apiname></xref> </p> <ul> |
|
155 <li id="GUID-99377F03-BA89-5DB0-AC4D-5F8892EB1F65"><p> <xref href="GUID-F98BADA5-852B-3859-B74A-B9747F79A754.dita"><apiname>KSoundRate7350Hz</apiname></xref> </p> </li> |
|
156 <li id="GUID-99FFC99B-740B-5809-9C75-C8CC1157F4E3"><p> <xref href="GUID-47512813-5787-3328-9980-399AA782E6A2.dita"><apiname>KSoundRate8000Hz</apiname></xref> </p> </li> |
|
157 <li id="GUID-D2C75BB5-5D8B-556B-A5BF-6A8C24D07D74"><p> <xref href="GUID-A622C93B-DF18-359D-B74A-0F90695900B7.dita"><apiname>KSoundRate8820Hz</apiname></xref> </p> </li> |
|
158 <li id="GUID-83D98EBD-AD0E-588E-8CFD-59B44C22FE6A"><p> <xref href="GUID-165180AC-1227-30BF-97DA-860C3AC3AA4E.dita"><apiname>KSoundRate9600Hz</apiname></xref> </p> </li> |
|
159 <li id="GUID-8D99D6B7-7FA7-5B8A-BEB9-2D982273C201"><p> <xref href="GUID-8DF1D395-4AC1-38AA-9F6A-C8867B1F4A60.dita"><apiname>KSoundRate11025Hz</apiname></xref> </p> </li> |
|
160 <li id="GUID-98353A3A-EFAC-5B6C-A779-8F12BB9150BA"><p> <xref href="GUID-512150A4-0796-3016-9CBC-83117E2930ED.dita"><apiname>KSoundRate12000Hz</apiname></xref> </p> </li> |
|
161 <li id="GUID-C27DD198-13FA-522A-9079-0BAA37094E16"><p> <xref href="GUID-892B4698-4914-348B-AB88-A1AC33D1E5EE.dita"><apiname>KSoundRate14700Hz</apiname></xref> </p> </li> |
|
162 <li id="GUID-71087DE2-06A9-536A-94DF-74FFFCB2F0DF"><p> <xref href="GUID-1A199051-5D76-396B-AA44-89506A128BFF.dita"><apiname>KSoundRate16000Hz</apiname></xref> </p> </li> |
|
163 <li id="GUID-666FA027-30AF-593B-894B-443B5C57E2DF"><p> <xref href="GUID-4021CE80-6667-36BB-9839-583E84AB9E83.dita"><apiname>KSoundRate22050Hz</apiname></xref> </p> </li> |
|
164 <li id="GUID-9D0D7E14-1FBE-5C80-A108-D3903D57ED49"><p> <xref href="GUID-73C38AA3-92AD-3EF0-BF60-3A207CD29C0E.dita"><apiname>KSoundRate24000Hz</apiname></xref> </p> </li> |
|
165 <li id="GUID-721DCA57-6E9B-5B02-9EA4-7640C652C5CE"><p> <xref href="GUID-9092C33B-C406-3044-AC8F-885F3EAE8B86.dita"><apiname>KSoundRate29400Hz</apiname></xref> </p> </li> |
|
166 <li id="GUID-5362CD78-1981-559B-9E1B-C999CDC8E3D9"><p> <xref href="GUID-0237DB93-3C16-3DCF-836E-CDECE95EAB1E.dita"><apiname>KSoundRate32000Hz</apiname></xref> </p> </li> |
|
167 <li id="GUID-61D0A788-2160-538F-82DB-414E6A34EC97"><p> <xref href="GUID-D3045D52-3092-3CCA-9AA5-05DE1ACAB92C.dita"><apiname>KSoundRate44100Hz</apiname></xref> </p> </li> |
|
168 <li id="GUID-28474DAC-AD25-506B-9112-F56825F845D2"><p> <xref href="GUID-DBD2AD6A-79F9-3D94-B6CB-1ED1E45F401A.dita"><apiname>KSoundRate48000Hz</apiname></xref> </p> </li> |
|
169 </ul> </li> |
|
170 <li id="GUID-CB112345-C035-5F7E-9AE5-B5222FF4F0A9"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-21F664A7-046E-3B1F-8C0B-A8B0EC0EC16C"><apiname>TSoundFormatsSupportedV02::iEncodings</apiname></xref> </p> <ul> |
|
171 <li id="GUID-F5833DD3-D273-5B62-9F4B-FEEC51D8CDF2"><p> <xref href="GUID-5BE58F42-47B2-3EB8-9F3B-DEF019C79499.dita"><apiname>KSoundEncodings8BitPCM</apiname></xref> </p> </li> |
|
172 <li id="GUID-B58CB616-CDCD-5CD0-AEC4-622F5AAB2474"><p> <xref href="GUID-790BA733-2B34-33B2-BF7B-7113DB1856A6.dita"><apiname>KSoundEncodings16BitPCM</apiname></xref> </p> </li> |
|
173 <li id="GUID-A4019328-CC8B-5224-8808-F3822230C389"><p> <xref href="GUID-EAB5A509-B0D6-3E2F-8106-D87A7C9D504F.dita"><apiname>KSoundEncodings24BitPCM</apiname></xref> </p> </li> |
|
174 </ul> </li> |
|
175 <li id="GUID-52DDB751-925B-5CC5-81F9-6F65A9D2039E"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-7950BC29-5C2E-34E0-B037-DDDDE0261DB7"><apiname>TSoundFormatsSupportedV02::iDataFormats</apiname></xref> </p> <ul> |
|
176 <li id="GUID-AD7EA560-7914-5D9D-B548-14DB3FA4AC7A"><p> <xref href="GUID-E02D661C-430F-306F-BD12-42238A91D83A.dita"><apiname>KSoundDataFormatInterleaved</apiname></xref> </p> </li> |
|
177 <li id="GUID-36EAAA69-B18A-555A-9646-FB8F6EC66505"><p> <xref href="GUID-ACC09AC6-A29B-3926-8AE4-4DA60416A3C1.dita"><apiname>KSoundDataFormatNonInterleaved</apiname></xref> </p> </li> |
|
178 </ul> </li> |
|
179 <li id="GUID-905CC707-760B-52F3-A942-0ADA02B69FA8"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-6F2D37B3-C465-3C77-A861-7FF9061F8EB9"><apiname>TSoundFormatsSupportedV02::iRequestMinSize</apiname></xref> </p> </li> |
|
180 <li id="GUID-8FCD4F3E-F70F-5E1B-8952-B667DC9D4AD2"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-472BCD65-11CE-3AEE-8DAE-9E56523AC096"><apiname>TSoundFormatsSupportedV02::iRequestAlignment</apiname></xref> </p> </li> |
|
181 <li id="GUID-749CE201-0554-5202-ABFC-FF9C0C4B1C1A"><p> <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita#GUID-39915413-31A6-360F-9758-5DBDF9D70103/GUID-AB35243B-ECD9-3268-A6FF-5079D1A45EA0"><apiname>TSoundFormatsSupportedV02::iHwConfigNotificationSupport</apiname></xref> </p> </li> |
|
182 </ul> <p>Many of the attribute ranges are passed as bit settings, and can |
|
183 assume all the values independently of one another. </p> <p>The following |
|
184 is a portion of the <xref href="GUID-161BA615-FD2C-3A7E-992E-FBBED621CBBB.dita"><apiname>Caps()</apiname></xref> function for the template port |
|
185 for the playback path of the AC97 Controller Unit (UCB140) codec device. </p> <p>The |
|
186 PDD maintains a <xref href="GUID-39915413-31A6-360F-9758-5DBDF9D70103.dita"><apiname>TSoundFormatsSupportedV02</apiname></xref> object as one |
|
187 of its data members named <codeph>iCaps</codeph>. The contents of <codeph>iCaps</codeph> is |
|
188 copied into the descriptor and passed as an argument to the <xref href="GUID-161BA615-FD2C-3A7E-992E-FBBED621CBBB.dita"><apiname>Caps()</apiname></xref> function: </p> <codeblock id="GUID-21B70DCD-7133-53A1-AE5C-848E0F68DF43" xml:space="preserve">void DTemplateSoundScTxPdd::Caps(TDes8& aCapsBuf) const |
|
189 { |
|
190 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::Caps")); |
|
191 |
|
192 // Copy iCaps back. |
|
193 TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); |
|
194 aCapsBuf.FillZ(aCapsBuf.MaxLength()); |
|
195 aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); |
|
196 } |
|
197 </codeblock> <p>The data member <codeph>iCaps</codeph> is initialised by the |
|
198 function <xref href="GUID-681FB26E-0027-38E6-88A1-9E9046011312.dita"><apiname>SetCaps()</apiname></xref> called from the second stage constructor |
|
199 of the PDD object: </p> <codeblock id="GUID-B17BA93D-14D6-56A9-8F1F-9FFEF88559D3" xml:space="preserve">void DTemplateSoundScTxPdd::SetCaps() |
|
200 { |
|
201 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetCaps")); |
|
202 |
|
203 // The data transfer direction for this unit is play. |
|
204 iCaps.iDirection=ESoundDirPlayback; |
|
205 |
|
206 // TO DO: (mandatory) |
|
207 // Setup the rest of the capabilities structure DTemplateSoundScTxPdd::iCaps with the capabilities of this |
|
208 // audio playback device. |
|
209 }</codeblock> </section> |
|
210 <section id="GUID-A2A7A6FF-8F46-589D-B5D6-E33ED3FF0692"><title>MaxTransferLen()</title> <p>Implement |
|
211 the <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> function for both playback |
|
212 and record driver channels. The function has the following signature: </p> <codeblock id="GUID-039E8EF1-AA13-5C38-92DD-46AFC8E1E8F3" xml:space="preserve">TInt DSoundScPdd::MaxTransferLen() const</codeblock> <p>The |
|
213 supplied implementation is as follows: </p> <codeblock id="GUID-E27E52F5-175A-5264-8B08-AE0BDAD5B495" xml:space="preserve">TInt DTemplateSoundScTxPdd::MaxTransferLen() const |
|
214 { |
|
215 return(KTemplateMaxTxDmaTransferLen); |
|
216 }</codeblock> <p>This function is called each time the LDD alters the |
|
217 audio configuration of the channel. For example, after calling <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>. |
|
218 The LDD uses the value returned to fragment record and playback data transfers |
|
219 so that they are manageable by the PDD. See <xref href="GUID-15FDDEED-89F1-5BE5-97AD-8DFD3640369A.dita">playback</xref> and <xref href="GUID-4AEF7595-17C0-513E-9568-B212E6194388.dita">record</xref>. </p> <p>The |
|
220 value returned by <xref href="GUID-615DF55C-EC50-3BF0-9C46-AB24E9505C5E.dita"><apiname>MaxTransferLen()</apiname></xref> is not as important |
|
221 for PDDs that use the Symbian DMA framework because the DMA framework handles |
|
222 fragmentation. </p> <p>If the PDD has to employ mono-to-stereo data conversion |
|
223 using a conversion buffer when configured in mono mode, then it needs to return |
|
224 the value that corresponds with the size of the conversion buffer each time |
|
225 it is configured in mono mode. See <xref href="GUID-E2641957-8163-5EF4-B282-FC3FD9CA75A6.dita#GUID-E2641957-8163-5EF4-B282-FC3FD9CA75A6/GUID-5C66667B-55C0-521D-86E3-67593DB381C9">mono |
|
226 to stereo conversion</xref>. </p> </section> |
|
227 <section id="GUID-B72057E6-B93C-505F-9789-83251D09B78E"><title>PowerUp()</title> <p>Implement |
|
228 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-6301A4AA-CC41-3DBC-A349-9BD5C9B01276"><apiname>DSoundScPdd::PowerUp</apiname></xref> function for both the playback |
|
229 and record driver channels. The function has the following signature: </p> <codeblock id="GUID-F9706BE3-125F-56B3-947E-3534FB3A5D23" xml:space="preserve">TInt DSoundScPdd::PowerUp()</codeblock> <p>The |
|
230 supplied implementation is as follows: </p> <codeblock id="GUID-DB986B0B-CC10-5842-BB54-76683A35EB38" xml:space="preserve">TInt DTemplateSoundScTxPdd::PowerUp() |
|
231 { |
|
232 // TO DO: (mandatory) |
|
233 // Power up the audio device. |
|
234 |
|
235 return(KErrNone); |
|
236 }</codeblock> <p>This function initialises the codec device and any associated |
|
237 controller hardware that allows the CPU to communicate with it. However, at |
|
238 this stage only basic initialisation of these hardware components is required, |
|
239 as the specific audio configuration has not yet been specified, and data transfer |
|
240 has not yet started. </p> <p>If the PDD supports both record and playback |
|
241 driver channels then most, if not all, of this hardware initialisation is |
|
242 common to both channels. It may be necessary to ensure that such initialisation |
|
243 on one channel cannot interfere with the other. For example, when calling <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-1B2E2F89-75A8-3740-893A-4DCDB0A350D3"><apiname>DSoundScPdd::PowerUp()</apiname></xref> on |
|
244 the record driver channel while the playback driver channel is active, make |
|
245 sure that it does not interfere with audio playback. This typically requires |
|
246 hardware status information to be held in the PDD factory object that is common |
|
247 to both channels. </p> </section> |
|
248 <section id="GUID-3764C238-A458-5D13-8AB2-EE53CA91F6E5"><title>SetConfig()</title> <p>Implement |
|
249 the <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> function for both playback |
|
250 and record driver channels. The function has the following signature: </p> <codeblock id="GUID-DB782F12-E5CE-5D13-8C12-8E57AB47BDB4" xml:space="preserve">TInt DSoundScPdd::SetConfig(const TDesC8& aConfigBuf)</codeblock> <codeblock id="GUID-868A3301-3CAD-5077-88AC-2A2A6C125AFD" xml:space="preserve">TInt DTemplateSoundScTxPdd::SetConfig(const TDesC8& aConfigBuf) |
|
251 { |
|
252 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetConfig")); |
|
253 |
|
254 // Read the new configuration from the LDD. |
|
255 TCurrentSoundFormatV02 config; |
|
256 TPtr8 ptr((TUint8*)&config,sizeof(config)); |
|
257 Kern::InfoCopy(ptr,aConfigBuf); |
|
258 |
|
259 // TO DO: (mandatory) |
|
260 // Apply the specified audio configuration to the audio device. |
|
261 TInt r=KErrNone; |
|
262 |
|
263 __KTRACE_SND(Kern::Printf("<DTemplateSoundScTxPdd::SetConfig - %d",r)); |
|
264 return(r); |
|
265 }</codeblock> <p>A configuration buffer in a packaged <xref href="GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68.dita"><apiname>TCurrentSoundFormatV02</apiname></xref> object |
|
266 containing the new configuration settings. </p> <ul> |
|
267 <li id="GUID-2D88064E-2258-55FA-BE68-831889E9E2C8"><p> <xref href="GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68.dita#GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68/GUID-AE4EDE94-5902-3D73-BAE4-4A49B3E3CC6C"><apiname>TCurrentSoundFormatV02::iChannels</apiname></xref> </p> </li> |
|
268 <li id="GUID-CBACC0C9-1C73-59E0-BAA4-63110DECDED9"><p> <xref href="GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68.dita#GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68/GUID-FA39A28F-4B0C-3B89-AB4B-763E0369AD31"><apiname>TCurrentSoundFormatV02::iRate</apiname></xref> </p> <ul> |
|
269 <li id="GUID-00FD1F5A-7941-5ED8-9878-69EDAE03F630"><p> <xref href="GUID-306655BD-FD24-37CE-8F67-F6BC5FBAA455.dita"><apiname>ESoundRate7350Hz</apiname></xref> </p> </li> |
|
270 <li id="GUID-3BEB74D8-B829-5B49-A740-F4BC0597E389"><p> <xref href="GUID-F6D595E9-BE6E-3D5F-AEEF-57FEBA5D165F.dita"><apiname>ESoundRate8000Hz</apiname></xref> </p> </li> |
|
271 <li id="GUID-E077B1A6-A625-55C8-8587-96EF7242C5F0"><p> <xref href="GUID-256AD4BA-8D30-38B8-8AC3-A63AFDCDF82E.dita"><apiname>ESoundRate8820Hz</apiname></xref> </p> </li> |
|
272 <li id="GUID-5664E1E2-DBC3-5F2C-A5BD-3EE5512C254E"><p> <xref href="GUID-3A48C172-FEEF-3A5A-A986-E5C1FD8E5048.dita"><apiname>ESoundRate9600Hz</apiname></xref> </p> </li> |
|
273 <li id="GUID-7E607F76-3975-591F-AEE3-D4CBC2B0F003"><p> <xref href="GUID-0B13D3F1-57D0-3741-BCC8-3E3BE50B59DE.dita"><apiname>ESoundRate11025Hz</apiname></xref> </p> </li> |
|
274 <li id="GUID-8054CF86-27CF-531A-9233-C6602BB958EF"><p> <xref href="GUID-88C3603E-D69F-3DE9-9AA0-F6F724432C76.dita"><apiname>ESoundRate12000Hz</apiname></xref> </p> </li> |
|
275 <li id="GUID-1AD1415C-0D0D-508F-B63E-69B553AA4109"><p> <xref href="GUID-D49E0BA6-AB68-334A-BECF-7221996C71CF.dita"><apiname>ESoundRate14700Hz</apiname></xref> </p> </li> |
|
276 <li id="GUID-1D23B890-0AFC-5E2B-8D00-E56CF1E75D07"><p> <xref href="GUID-6FDDFE56-B32E-3DA1-8E90-DCAE1476A75F.dita"><apiname>ESoundRate16000Hz</apiname></xref> </p> </li> |
|
277 <li id="GUID-A2637B2C-AD6B-5A87-86AC-FDB56DBF46C0"><p> <xref href="GUID-86882923-4DB3-3461-AF9E-D36BF75125AB.dita"><apiname>ESoundRate22050Hz</apiname></xref> </p> </li> |
|
278 <li id="GUID-8682C600-A7C8-5B8B-9824-DD670812C598"><p> <xref href="GUID-2E1FC700-5B43-39DE-8B67-7DADD38B55A5.dita"><apiname>ESoundRate24000Hz</apiname></xref> </p> </li> |
|
279 <li id="GUID-51A42D66-5B71-5325-90B7-B5A1503F21C5"><p> <xref href="GUID-244A1091-0F4A-376B-AE3E-93F09029ECF0.dita"><apiname>ESoundRate29400Hz</apiname></xref> </p> </li> |
|
280 <li id="GUID-04621385-220C-587B-9C59-68115E251D8C"><p> <xref href="GUID-1C1526A2-4BA2-3296-BBE0-152070B43EE9.dita"><apiname>ESoundRate32000Hz</apiname></xref> </p> </li> |
|
281 <li id="GUID-5DECBAD3-09E7-5967-82B3-7C923F870DA6"><p> <xref href="GUID-028FCDA8-E1FC-3E5D-827B-E4513991C1F2.dita"><apiname>ESoundRate44100Hz</apiname></xref> </p> </li> |
|
282 <li id="GUID-27AA4D39-3CA5-52A0-9F97-C8543AAECB97"><p> <xref href="GUID-14D9C50A-2F72-3D1D-A15B-BDE4FAA33ED8.dita"><apiname>ESoundRate48000Hz</apiname></xref> </p> </li> |
|
283 </ul> </li> |
|
284 <li id="GUID-95DDDF4C-B70E-56B1-92E6-616ADCB45025"><p> <xref href="GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68.dita#GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68/GUID-1A4256A2-A2FE-3FD0-8849-A9F37E1D7A77"><apiname>TCurrentSoundFormatV02::iEncoding</apiname></xref> </p> <ul> |
|
285 <li id="GUID-48484A2E-6970-59AE-9CD5-C93BE349C28D"><p> <xref href="GUID-866386CC-C9CA-3029-95C2-800F6B6C3C2D.dita"><apiname>ESoundEncoding8BitPCM</apiname></xref> </p> </li> |
|
286 <li id="GUID-357130A0-C112-5803-A4D3-9B1237B5931C"><p> <xref href="GUID-E69FCDC5-9A22-3C5A-89C9-A7B869744948.dita"><apiname>ESoundEncoding16BitPCM</apiname></xref> </p> </li> |
|
287 <li id="GUID-E2920329-BDFC-5B28-BF53-F4CF45DBE9AC"><p> <xref href="GUID-289CBD4B-ACEF-3A43-8935-201635AC658F.dita"><apiname>ESoundEncoding24BitPCM</apiname></xref> </p> </li> |
|
288 </ul> </li> |
|
289 <li id="GUID-406F8EE9-885D-5569-98E0-A473BB7462FB"><p> <xref href="GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68.dita#GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68/GUID-3A9546CB-33D6-3171-A8F7-0E642EB8E798"><apiname>TCurrentSoundFormatV02::iDataformat</apiname></xref> </p> <ul> |
|
290 <li id="GUID-D21416A0-3E78-5D5C-BFE3-0C8A75F80429"><p> <xref href="GUID-5ADC3C98-2D05-35E1-96D2-42B3A65BF25F.dita"><apiname>ESoundDateFormatInterleaved</apiname></xref> </p> </li> |
|
291 <li id="GUID-1A7EC2CC-D94F-514E-BB8A-9A3B3551B13F"><p> <xref href="GUID-352ED2EF-C98C-305E-80F1-FE30DF1BE4CA.dita"><apiname>ESoundDateFormatNonInterleaved</apiname></xref> </p> </li> |
|
292 </ul> </li> |
|
293 </ul> <p>The PDD must read and locally save the contents of the <xref href="GUID-EF1D41AB-929D-3E51-98AA-F175DDB58F68.dita"><apiname>TCurrentSoundFormatV02</apiname></xref> configuration |
|
294 object that has been passed as a descriptor from the LDD. The template version |
|
295 contains the following code to achieve this: </p> <codeblock id="GUID-7FF5383E-FAE0-51A7-8E9E-0F489D841C72" xml:space="preserve">// Read the new configuration from the LDD. |
|
296 TCurrentSoundFormatV02 config; |
|
297 TPtr8 ptr((TUint8*)&config, sizeof(config)); |
|
298 Kern::InfoCopy(ptr, aConfigBuf);</codeblock> <p>It is not necessary to check |
|
299 for configurations requested by the LDD that are not supported by the audio |
|
300 hardware device if the <xref href="GUID-161BA615-FD2C-3A7E-992E-FBBED621CBBB.dita"><apiname>Caps()</apiname></xref> function has been implemented |
|
301 correctly by the PDD. This is because the LDD rejects such audio configuration |
|
302 requests from the client. However, if the PDD supports both playback and record |
|
303 driver channels then it needs to check that the specified configuration does |
|
304 not conflict with one already in use by the other channel. </p> <p>The PDD |
|
305 sets up the audio hardware device according to the audio configuration specified |
|
306 if it is required. Some, if not all of this hardware configuration may be |
|
307 put off until data transfer is started, this is when <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> is |
|
308 called, so for now the PDD needs to save the configuration. </p> <p>If the |
|
309 PDD has to employ mono-to-stereo conversion of data using a conversion buffer |
|
310 while the audio configuration is set to mono, then the memory for the conversion |
|
311 buffer should be allocated at this time. </p> </section> |
|
312 <section id="GUID-51420A2F-180B-5916-AF5A-685ABD156A2D"><title>SetVolume()</title> <p>Implement |
|
313 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-3C56E870-1F05-31BC-B799-AF49F77E2930"><apiname>DSoundScPdd::SetVolume</apiname></xref> function for both the playback |
|
314 and record driver channels. This has the following signature: </p> <codeblock id="GUID-6FEA0876-7753-54C7-A414-9A54913F1778" xml:space="preserve">TInt DSoundScPdd::SetVolume(TInt aVolume)</codeblock> <p>The |
|
315 supplied implementation is as follows: </p> <codeblock id="GUID-14196DC5-8630-5E06-869A-D9A5EE423BF6" xml:space="preserve">TInt DTemplateSoundScTxPdd::SetVolume(TInt aVolume) |
|
316 { |
|
317 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetVolume")); |
|
318 |
|
319 // TO DO: (mandatory) |
|
320 // Set the specified play volume on the audio device. |
|
321 TInt r=KErrNone; |
|
322 |
|
323 return(r); |
|
324 }</codeblock> <p>The PDD must first convert the volume/record level information |
|
325 specified into a form which can be used to program the hardware. This may |
|
326 require converting the value from a gain factor to an attenuation factor and/or |
|
327 applying a scaling factor. The LDD detects situations where the client specifies |
|
328 a record level /volume that is already in effect, and in this case does not |
|
329 unnecessarily call the PDD. </p> <p>The PDD may opt to setup the audio hardware |
|
330 device within this function or it may defer this until data transfer is started |
|
331 with the function <xref href="GUID-CCACE58D-8884-37A4-B7DB-F1DFDEE4A8F1.dita#GUID-CCACE58D-8884-37A4-B7DB-F1DFDEE4A8F1/GUID-788592C9-FCCA-3E34-BEA7-5DC5E6A497C8"><apiname>DSOundScPdd::StartTransfer()</apiname></xref>. For PDDs |
|
332 which support both record and playback driver channels, it is normal for audio |
|
333 devices to allow the record and playback gains to be programmed independently, |
|
334 this means that checking for conflicts between the channels is rarely required |
|
335 for this function. </p> </section> |
|
336 <section id="GUID-287BB55C-E0FD-5214-9FAA-857AB46C64ED"><title>StartTransfer()</title> <p>Implement |
|
337 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-66F3D9DA-F61F-3C1D-8C95-02C7C561AE64"><apiname>DSoundScPdd::StartTransfer</apiname></xref> function for both the playback |
|
338 and record driver channels. This has the following signature: </p> <codeblock id="GUID-02F7B0B7-35A7-525C-A88D-6555113D6D62" xml:space="preserve">TInt DSoundScPdd::StartTransfer()</codeblock> <p>The |
|
339 supplied implementation is as follows: </p> <codeblock id="GUID-DE7BF31A-B5D4-5348-9280-0C326D37DAF8" xml:space="preserve">TInt DTemplateSoundScTxPdd::StartTransfer() |
|
340 { |
|
341 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::StartTransfer")); |
|
342 |
|
343 // TO DO: (mandatory) |
|
344 // Prepare the audio device for playback. |
|
345 TInt r=KErrNone; |
|
346 |
|
347 __KTRACE_SND(Kern::Printf("<DTemplateSoundScTxPdd::StartTransfer - %d",r)); |
|
348 return(r); |
|
349 }</codeblock> <p>This function performs any configurations of the audio |
|
350 hardware device that were deferred from the <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> function. |
|
351 These configurations may include start-up of the DMA engine, enabling any |
|
352 interrupts related to audio transfer and interrupts that detect error conditions, |
|
353 for example. At this stage, no data has yet been supplied to the device for |
|
354 transfer as the function <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> has |
|
355 not yet been called. </p> <p>If the PDD supports both record and playback |
|
356 driver channels then it may be necessary to ensure that such hardware configuration |
|
357 on one channel cannot interfere with the other. </p> </section> |
|
358 <section id="GUID-5E29637F-140F-5F1B-B969-DF9682CEF5E2"><title>TransferData()</title> <p>Implement |
|
359 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-EF749829-6C35-3954-A48D-483FD0182CC9"><apiname>DSoundScPdd::TransferData</apiname></xref> function for both playback |
|
360 and record driver channels. This has the following signature: </p> <codeblock id="GUID-F13C3C46-D208-5E24-B986-3A32FAFBE453" xml:space="preserve">TInt DSoundScPdd::TransferData(TUint aTransferID,TLinAddr aLinAddr, |
|
361 TPhysAddr aPhysAddr,TInt aNumBytes)</codeblock> <p>Once |
|
362 transfer has been started by calling <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>, |
|
363 the function <xref href="GUID-209D8909-56BD-3601-98C4-FB6E004D78EE.dita"><apiname>TransferData</apiname></xref> is called repeatedly by the LDD |
|
364 for the transfer of each fragment. See the <xref href="GUID-15FDDEED-89F1-5BE5-97AD-8DFD3640369A.dita">playback</xref> and <xref href="GUID-4AEF7595-17C0-513E-9568-B212E6194388.dita">record</xref> sections for |
|
365 details. </p> <p>The template version for the record driver channel contains |
|
366 the following code: </p> <codeblock id="GUID-C86982D4-A2FE-5904-A46C-D52D349D018E" xml:space="preserve">TInt DTemplateSoundScRxPdd::TransferData(TUint aTransferID, TLinAddr aLinAddr, |
|
367 TPhysAddr /*aPhysAddr*/, TInt aNumBytes) |
|
368 { |
|
369 TInt r=KErrNone; |
|
370 |
|
371 // Check that we can accept the request |
|
372 if (iPendingRecord>=KTemplateMaxRxDmaRequests) |
|
373 r=KErrNotReady; |
|
374 else |
|
375 { |
|
376 // Start a DMA transfer. |
|
377 iDmaRequest[iFlag]->iTransferID=aTransferID; |
|
378 iDmaRequest[iFlag]->iTransferSize=aNumBytes; |
|
379 // TO DO: (mandatory) |
|
380 // Supply the DMA source information. |
|
381 TUint32 src=0; // ??? |
|
382 r=iDmaRequest[iFlag]->Fragment(src,aLinAddr,aNumBytes,KDmaMemDest|KDmaIncDest,0); |
|
383 if (r==KErrNone) |
|
384 { |
|
385 iDmaRequest[iFlag]->Queue(); |
|
386 iPendingRecord++; |
|
387 if ((++iFlag)>=KTemplateMaxRxDmaRequests) |
|
388 iFlag=0; |
|
389 |
|
390 // TO DO: (mandatory) |
|
391 // Start the audio device transferring data. |
|
392 } |
|
393 } |
|
394 |
|
395 return(r); |
|
396 }</codeblock> <p><note> The template version used by the playback function |
|
397 is very similar. </note></p> <p>The first step is for the PDD to check that |
|
398 it has the capacity to accept a further transfer. For example, check that |
|
399 the PDD has a DMA request object that is free and that the DMA controller |
|
400 has the capacity for another transfer to be queued. If the PDD does not have |
|
401 the capacity to accept another transfer then it should immediately return <xref href="GUID-51298FCE-7857-39F8-BFAB-49AF5556D0CC.dita"><apiname>KErrNotReady</apiname></xref> to |
|
402 signal this. </p> <p>Otherwise, the PDD can start a DMA transfer. To do this |
|
403 it must acquire a DMA request object. The class <xref href="GUID-6B0DB695-9033-3F85-AC3A-1867E99BE2BD.dita"><apiname>DTemplateSoundScRxDmaRequest</apiname></xref> is |
|
404 the abstraction for a DMA record request and is defined as follows: </p> <codeblock id="GUID-04B1D7FD-4E17-5CD0-974F-A3A1BCB04C58" xml:space="preserve">/** Wrapper function for a shared chunk sound driver record DMA request. */ |
|
405 class DTemplateSoundScRxDmaRequest : public DDmaRequest |
|
406 { |
|
407 public: |
|
408 DTemplateSoundScRxDmaRequest(TDmaChannel& aChannel, DTemplateSoundScRxPdd* aPdd, |
|
409 TInt aMaxTransferSize=0); |
|
410 static void DmaService(TResult aResult, TAny* aArg); |
|
411 public: |
|
412 /** Pointer back to the PDD. */ |
|
413 DTemplateSoundScRxPdd* iPdd; |
|
414 /** The transfer ID for this DMA request - supplied by the LDD. */ |
|
415 TUint iTransferID; |
|
416 /** The transfer sizes in progress. */ |
|
417 TUint iTransferSize; |
|
418 }; |
|
419 This is derived from DDmaRequest the base class |
|
420 for a DMA request.</codeblock> <p>The data member <codeph>iPdd</codeph> is |
|
421 a pointer to the owning PDD object. This is used within the member function <xref href="GUID-8B538AA6-9489-309F-8756-2474310CD5DA.dita"><apiname>DmaService()</apiname></xref> which |
|
422 is the DMA callback function, and is called when the DMA request has been |
|
423 completed by the DMA framework. The data member <codeph>iTransferID</codeph> is |
|
424 a value supplied by the LDD which it uses to identify the transfer fragment. |
|
425 The PDD must save this value and pass it back to the LDD when the transfer |
|
426 is completed. Similarly, the member <codeph>iTransferSize</codeph> is used |
|
427 to hold the length of the transfer fragment in bytes. If the transfer is successful |
|
428 then this value is also passed back to the LDD to allow it to maintain its |
|
429 count of bytes recorded. </p> <p>The record PDD class owns an array of DMA |
|
430 request objects: </p> <codeblock id="GUID-8314BE9B-2D19-585F-B44E-17C8529CEFEF" xml:space="preserve">/** The DMA request structures used for transfers. */ |
|
431 DTemplateSoundScRxDmaRequest* iDmaRequest[KTemplateMaxRxDmaRequests];</codeblock> <p>It |
|
432 also owns the data member <codeph>iFlag</codeph>, which always holds the number |
|
433 for the next DMA request that should be used for transfer. Before starting |
|
434 the DMA transfer, setup the appropriate DMA request object with the transfer |
|
435 ID and the transfer length. </p> <codeblock id="GUID-2F4CB025-C2E2-52DD-A679-CF1DCC3677FA" xml:space="preserve">/** A flag selecting the next DMA request for transfer. */ |
|
436 TInt iFlag;</codeblock> <p>Next the function <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita#GUID-780F4D53-5546-3B69-B328-0226C70EBDE2/GUID-B14B0478-80D6-3F5E-88B6-1676411D9CF2"><apiname>DDmaRequest::Fragment()</apiname></xref> is |
|
437 called to specify the details of the transfer to the DMA framework and to |
|
438 allow it to analyse this. Here the appropriate platform specific 32-bit DMA |
|
439 source identifier, <codeph>src</codeph>, needs to be supplied. The template |
|
440 driver shown previously specifies the destination memory address as a linear |
|
441 address but the physical address may be used instead. Both forms of this address |
|
442 are passed as arguments to the <xref href="GUID-34E7FF1F-091A-3C45-B83A-AEB64E2AD286.dita"><apiname>TransferData()</apiname></xref> function. </p> <p>If |
|
443 fragmentation is successful then the request object is queued on the DMA channel <xref href="GUID-780F4D53-5546-3B69-B328-0226C70EBDE2.dita#GUID-780F4D53-5546-3B69-B328-0226C70EBDE2/GUID-0A83F782-DB62-39ED-8D32-DBD5949C8D3F"><apiname>DDmaRequest::Queue()</apiname></xref> and |
|
444 the value of <codeph>iFlag</codeph> is updated ready for the next transfer. |
|
445 The PDD class also keeps a count of the number of transfer fragments outstanding |
|
446 by incrementing the variable <codeph>iPendingRecord</codeph>: </p> <codeblock id="GUID-5C738134-0683-5FAB-8733-29D9A336402F" xml:space="preserve">/** The number of outstanding DMA record requests on the DMA channel. */ |
|
447 TInt iPendingRecord;</codeblock> <p>The final part of this function requires |
|
448 platform specific code to start the audio hardware device transferring data. |
|
449 This needs to be executed for each fragment transferred or just for the first |
|
450 fragment queued following the <xref href="GUID-FE6DE994-719C-3900-B4A0-009914697380.dita"><apiname>StartTransfer()</apiname></xref> function. </p> <p>Once |
|
451 the transfer is complete, either successfully or with an error, the DMA framework |
|
452 executes the static DMA callback function, <xref href="GUID-6B0DB695-9033-3F85-AC3A-1867E99BE2BD.dita#GUID-6B0DB695-9033-3F85-AC3A-1867E99BE2BD/GUID-E12BA027-3D58-30A8-A9F7-B7B7DC55D0D5"><apiname>DTemplateSoundScRxDmaRequest::DmaService()</apiname></xref>, |
|
453 as follows: </p> <codeblock id="GUID-2ED07474-F489-5545-9FB6-BC229C00D4F3" xml:space="preserve">/** |
|
454 DMA rx service routine. Called in the sound thread's DFC context by the s/w DMA controller. |
|
455 @param aResult Status of DMA transfer. |
|
456 @param aArg Argument passed to DMA controller. |
|
457 */ |
|
458 void DTemplateSoundScRxDmaRequest::DmaService(TResult aResult, TAny* aArg) |
|
459 { |
|
460 DTemplateSoundScRxDmaRequest& req=*(DTemplateSoundScRxDmaRequest*)aArg; |
|
461 |
|
462 TInt res=KErrNone; |
|
463 TInt bytesTransferred=req.iTransferSize; |
|
464 if (aResult!=DDmaRequest::EOk) |
|
465 { |
|
466 res=KErrCorrupt; |
|
467 bytesTransferred=0; |
|
468 } |
|
469 |
|
470 // Inform the LDD of the result of the transfer. |
|
471 req.iPdd->RecordCallback(req.iTransferID,res,bytesTransferred); |
|
472 return; |
|
473 }</codeblock> <p>This function receives two arguments: </p> <ul> |
|
474 <li id="GUID-7D4D15BD-3BA0-5899-B67E-C7F24F548D22"><p>the result of the transfer |
|
475 from the DMA framework </p> </li> |
|
476 <li id="GUID-FE18B3C9-A3B3-5599-8CC6-66977D0FA56A"><p>an argument supplied |
|
477 to the DMA framework when the request object was created </p> </li> |
|
478 </ul> <p>In this specific case, the argument type is a pointer to the DMA |
|
479 request object, and allows the retrieval of the transfer ID and the transfer |
|
480 size. In the template driver version an unsuccessful transfer returns an error |
|
481 value of <xref href="GUID-253F06EA-F14E-3A8E-BA4C-8E787B5F0670.dita"><apiname>KErrCorrupt</apiname></xref> with a transfer byte count of zero. </p> <p>From |
|
482 the callback function we call the record PDD function to decrement the count |
|
483 of transfer fragments outstanding and to inform the LDD of the completion |
|
484 of transfer. </p> <codeblock id="GUID-69C81D24-D725-51B2-8099-1D089A70AE00" xml:space="preserve">void DTemplateSoundScRxPdd::RecordCallback(TUint aTransferID, TInt aTransferResult,TInt aBytesTransferred) |
|
485 { |
|
486 iPendingRecord--; |
|
487 Ldd()->RecordCallback(aTransferID,aTransferResult,aBytesTransferred); |
|
488 } |
|
489 </codeblock> </section> |
|
490 <section id="GUID-E9B63AC5-4AED-53E3-B7CA-21AACE04FC37"><title>StopTransfer()</title> <p>Implement |
|
491 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-7C629A7C-0C64-32AB-8159-A4075DEEF544"><apiname>DSoundScPdd::StopTransfer</apiname></xref> function for both the play |
|
492 and record driver channels. This has the following signature: </p> <codeblock id="GUID-E56EFFEC-59CA-595F-BFA8-72299999DD05" xml:space="preserve">void DSoundScPdd::StopTransfer()</codeblock> <p>The |
|
493 PDD must reverse any operation performed on the audio hardware device done |
|
494 as part of <xref href="GUID-FE6DE994-719C-3900-B4A0-009914697380.dita"><apiname>StartTransfer()</apiname></xref> or <xref href="GUID-34E7FF1F-091A-3C45-B83A-AEB64E2AD286.dita"><apiname>TransferData()</apiname></xref>. |
|
495 This includes stopping the audio hardware device from transferring data and |
|
496 stopping the DMA channel. </p> <p>The template version for the record driver |
|
497 channel contains the following code: </p> <codeblock id="GUID-D8A0C5F9-3E9D-54F5-8906-465801CC3A3E" xml:space="preserve">void DTemplateSoundScRxPdd::StopTransfer() |
|
498 { |
|
499 // Stop the DMA channel. |
|
500 iDmaChannel->CancelAll(); |
|
501 iFlag=0; |
|
502 iPendingRecord=0; |
|
503 |
|
504 // TO DO: (mandatory) |
|
505 // Stop the audio device transferring data. |
|
506 }</codeblock> <p> <note> The version used by the playback function is |
|
507 very similar. </note></p> </section> |
|
508 <section id="GUID-2F694050-660B-5941-B9AA-FB21C1D33400"><title>PauseTransfer()</title> <p>Implement |
|
509 the <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> function for both the |
|
510 playback and record driver channels. This has the following signature: </p> <codeblock id="GUID-51C0B918-4883-574A-B1AF-476C61A85120" xml:space="preserve">TInt DSoundScPdd::PauseTransfer()</codeblock> <p>When |
|
511 pausing playback, there is normally some way to temporarily stop the codec |
|
512 and pause the DMA channel so that it can be resumed later starting from the |
|
513 next play sample. </p> <p>Pausing record requires a different implementation. |
|
514 All active transfers must be aborted. When this has been achieved, the PDD |
|
515 must report back to the LDD how much data has been received for the fragment |
|
516 that was actively being transferred when the abort took place by calling <xref href="GUID-5807543D-A30F-3EB9-8F28-91A623B0D484.dita#GUID-5807543D-A30F-3EB9-8F28-91A623B0D484/GUID-9112E399-DC3C-334F-BE16-B5F42216F903"><apiname>DSoundScLdd::RecordCallBack()</apiname></xref>. |
|
517 If it is not possible to determine the byte count for the last fragment from |
|
518 the DMA controller, then you must find some other way to discover its value. |
|
519 One solution is to re-start a timer at the start of each record fragment, |
|
520 and use this to calculate how much data will have been written into the record |
|
521 buffer at the point the transfer is aborted. </p><p><note> In this case the |
|
522 returned transfer ID is not important.</note> </p> <p>The supplied template |
|
523 implementation is as follows: </p> <codeblock id="GUID-5B5B290E-C751-5599-AA67-0AC59E697898" xml:space="preserve">TInt DTemplateSoundScRxPdd::PauseTransfer() |
|
524 { |
|
525 // Stop the DMA channel. |
|
526 iDmaChannel->CancelAll(); |
|
527 |
|
528 if (iPendingRecord) |
|
529 { |
|
530 // TO DO: (mandatory) |
|
531 // Determine how much data was successfully transferred to the |
|
532 // record buffer before transfer was aborted. |
|
533 TInt byteCount=0; // ??? |
|
534 Ldd()->RecordCallback(0,KErrNone,byteCount); |
|
535 iPendingRecord=0; |
|
536 } |
|
537 iFlag=0; |
|
538 |
|
539 // TO DO: (mandatory) |
|
540 // Halt recording on the audio device. |
|
541 TInt r=KErrNone; |
|
542 |
|
543 return(r); |
|
544 } |
|
545 </codeblock> <p> <note> There is no need for the PDD to perform any state |
|
546 checking as this is already performed by the LDD. For example, checking that |
|
547 the device is not already paused or transferring data. </note></p> </section> |
|
548 <section id="GUID-00368C95-2AE6-5EBA-8C09-787D0E7C10BC"><title>ResumeTransfer()</title> <p>Implement |
|
549 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-788AEAF9-E33A-3BD2-8B60-9A066DBA2496"><apiname>DSoundScPdd::ResumeTransfer</apiname></xref> function for both the playback |
|
550 and record driver channels. This has the following signature: </p> <codeblock id="GUID-81A86CB7-E089-5B3D-A28F-A371AFDF5471" xml:space="preserve">TInt DSoundScPdd::ResumeTransfer()</codeblock> <p>The |
|
551 template version for the record driver channel contains the following code: </p> <codeblock id="GUID-D72D3F34-197F-500F-8483-E307418127F6" xml:space="preserve">TInt DTemplateSoundScTxPdd::ResumeTransfer() |
|
552 { |
|
553 __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::ResumeTransfer")); |
|
554 |
|
555 // TO DO: (mandatory) |
|
556 // Resume playback on the audio device. |
|
557 TInt r=KErrNone; |
|
558 |
|
559 return(r); |
|
560 }</codeblock> <p>To resume playback, it is normally necessary to re-start |
|
561 the codec and resume the DMA channel in order to restart playback from the |
|
562 next play sample. </p> <p>To resume record, all active transfers should have |
|
563 been aborted when the device was paused with the function <xref href="GUID-1126E802-39C1-3BAD-85BA-A6DDED981B8A.dita"><apiname>PauseTransfer()</apiname></xref>. |
|
564 However, the LDD issues a new <xref href="GUID-34E7FF1F-091A-3C45-B83A-AEB64E2AD286.dita"><apiname>TransferData()</apiname></xref> request subsequent |
|
565 to this function to resume record data transfer so the only action required |
|
566 here is to recreate the same audio hardware setup that was achieved in response |
|
567 to the <xref href="GUID-FE6DE994-719C-3900-B4A0-009914697380.dita"><apiname>StartTransfer()</apiname></xref> function. </p> <p>There is no need |
|
568 for the PDD to perform any state checking as this is already performed by |
|
569 the LDD. For example, checking that the device is not already paused. </p> </section> |
|
570 <section id="GUID-3155494B-AFFD-5E07-8E2F-D6EC81E4E69B"><title>PowerDown()</title> <p>Implement |
|
571 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-53CDB4F4-470C-3A40-B948-C14B0FCA0E24"><apiname>DSoundScPdd::PowerDown()</apiname></xref> function for both the playback |
|
572 and record driver channels. This has the following signature: </p> <codeblock id="GUID-69B46DDC-DA62-55E2-9E7C-A4E0B1550E03" xml:space="preserve">void DSoundScPdd::PowerDown()</codeblock> <p>The |
|
573 PDD must reverse any operation performed on the audio hardware as part of <xref href="GUID-B70A3916-5644-330F-872B-FADB8E3D80B5.dita"><apiname>PowerUp()</apiname></xref>. </p> </section> |
|
574 <section id="GUID-4B71AE98-3692-54B3-9CD8-525991DBAEAA"><title>CustomConfig()</title> <p>Implement |
|
575 the <xref href="GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424.dita#GUID-61CC68CB-A01D-3CA0-93D9-F3717ABD6424/GUID-B0F89BCD-69AF-3D40-A601-EB22C6FA0435"><apiname>DSoundScPdd::CustomConfig()</apiname></xref> function for both the playback |
|
576 and record driver channels. This has the following signature: </p> <codeblock id="GUID-C24D93F2-9A7E-5E43-8750-6BE8978B9C01" xml:space="preserve">TInt DSoundScPdd::CustomConfig(TInt aFunction,TAny* aParam)</codeblock> <p> <xref href="GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3.dita#GUID-B0118EDD-2B08-353E-BE92-2DC75E5622B3/GUID-78AA2782-80D0-3815-8F71-AA218756BAE6"><apiname>RSoundSc::CustomConfig()</apiname></xref> is called by the LDD in response to a custom configuration request by the |
|
577 client. Custom configurations allow clients to issue requests to setup platform |
|
578 specific audio configuration settings. Any such requests from the client with |
|
579 a function identifier equal to or above 0x10000000 are passed straight through |
|
580 to the PDD for function identification and implementation. These are handled |
|
581 in the context of the sound driver DFC thread. </p> <p>If custom configuration |
|
582 is not supported, then the PDD should simply return <codeph>KErrNotSupported</codeph>. </p> </section> |
|
583 </conbody></concept> |