/[pcsx2_0.9.7]/branch/r3113_0.9.7_beta/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c
ViewVC logotype

Contents of /branch/r3113_0.9.7_beta/3rdparty/portaudio/src/os/win/pa_win_wdmks_utils.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 32 - (show annotations) (download)
Tue Sep 7 03:29:01 2010 UTC (9 years, 10 months ago) by william
File MIME type: text/plain
File size: 11312 byte(s)
branching from upstream revision (http://pcsx2.googlecode.com/svn/trunk
): r3113 to
https://svn.netsolutions.dnsalias.com/websvn/ps2/pcsx2/pcsx2_0.9.7/branch/r3113_0.9.7_beta
1 /*
2 * PortAudio Portable Real-Time Audio Library
3 * Windows WDM KS utilities
4 *
5 * Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files
9 * (the "Software"), to deal in the Software without restriction,
10 * including without limitation the rights to use, copy, modify, merge,
11 * publish, distribute, sublicense, and/or sell copies of the Software,
12 * and to permit persons to whom the Software is furnished to do so,
13 * subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 /*
28 * The text above constitutes the entire PortAudio license; however,
29 * the PortAudio community also makes the following non-binding requests:
30 *
31 * Any person wishing to distribute modifications to the Software is
32 * requested to send the modifications to the original developer so that
33 * they can be incorporated into the canonical version. It is also
34 * requested that these non-binding requests be included along with the
35 * license above.
36 */
37
38 #include <windows.h>
39 #include <mmreg.h>
40 #include <ks.h>
41 #include <ksmedia.h>
42 #include <stdio.h> // just for some development printfs
43
44 #include "portaudio.h"
45 #include "pa_util.h"
46 #include "pa_win_wdmks_utils.h"
47
48
49 #ifndef PA_WDMKS_NO_KSGUID_LIB
50
51 #if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
52 #pragma comment( lib, "ksguid.lib" )
53 #endif
54
55 #define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
56 #define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
57 #define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
58 #define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
59 #define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
60 #define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
61 #define pa_KSPROPSETID_Pin KSPROPSETID_Pin
62
63 #else
64
65 static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
66 static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
67 static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
68 static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
69 static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
70 static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
71 static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
72
73 #endif
74
75
76 #define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\
77 (!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
78
79
80
81 static PaError WdmGetPinPropertySimple(
82 HANDLE handle,
83 unsigned long pinId,
84 unsigned long property,
85 void* value,
86 unsigned long valueSize )
87 {
88 DWORD bytesReturned;
89 KSP_PIN ksPProp;
90 ksPProp.Property.Set = pa_KSPROPSETID_Pin;
91 ksPProp.Property.Id = property;
92 ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
93 ksPProp.PinId = pinId;
94 ksPProp.Reserved = 0;
95
96 if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
97 value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize )
98 {
99 return paUnanticipatedHostError;
100 }
101 else
102 {
103 return paNoError;
104 }
105 }
106
107
108 static PaError WdmGetPinPropertyMulti(
109 HANDLE handle,
110 unsigned long pinId,
111 unsigned long property,
112 KSMULTIPLE_ITEM** ksMultipleItem)
113 {
114 unsigned long multipleItemSize = 0;
115 KSP_PIN ksPProp;
116 DWORD bytesReturned;
117
118 *ksMultipleItem = 0;
119
120 ksPProp.Property.Set = pa_KSPROPSETID_Pin;
121 ksPProp.Property.Id = property;
122 ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
123 ksPProp.PinId = pinId;
124 ksPProp.Reserved = 0;
125
126 if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property,
127 sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA )
128 {
129 return paUnanticipatedHostError;
130 }
131
132 *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
133 if( !*ksMultipleItem )
134 {
135 return paInsufficientMemory;
136 }
137
138 if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
139 (void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize )
140 {
141 PaUtil_FreeMemory( ksMultipleItem );
142 return paUnanticipatedHostError;
143 }
144
145 return paNoError;
146 }
147
148
149 static int GetKSFilterPinCount( HANDLE deviceHandle )
150 {
151 DWORD result;
152
153 if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){
154 return result;
155 }else{
156 return 0;
157 }
158 }
159
160
161 static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId )
162 {
163 KSPIN_COMMUNICATION result;
164
165 if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){
166 return result;
167 }else{
168 return KSPIN_COMMUNICATION_NONE;
169 }
170 }
171
172
173 static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId )
174 {
175 KSPIN_DATAFLOW result;
176
177 if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){
178 return result;
179 }else{
180 return (KSPIN_DATAFLOW)0;
181 }
182 }
183
184
185 static int KSFilterPinPropertyIdentifiersInclude(
186 HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
187 {
188 KSMULTIPLE_ITEM* item = NULL;
189 KSIDENTIFIER* identifier;
190 int i;
191 int result = 0;
192
193 if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
194 return 0;
195
196 identifier = (KSIDENTIFIER*)(item+1);
197
198 for( i = 0; i < (int)item->Count; i++ )
199 {
200 if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) &&
201 ( identifier[i].Id == identifierId ) )
202 {
203 result = 1;
204 break;
205 }
206 }
207
208 PaUtil_FreeMemory( item );
209
210 return result;
211 }
212
213
214 /* return the maximum channel count supported by any pin on the device.
215 if isInput is non-zero we query input pins, otherwise output pins.
216 */
217 int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput )
218 {
219 HANDLE deviceHandle;
220 ULONG i;
221 int pinCount, pinId;
222 int result = 0;
223 KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
224
225 if( !wcharDevicePath )
226 return 0;
227
228 deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
229 if( deviceHandle == INVALID_HANDLE_VALUE )
230 return 0;
231
232 pinCount = GetKSFilterPinCount( deviceHandle );
233 for( pinId = 0; pinId < pinCount; ++pinId )
234 {
235 KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId );
236 KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
237 if( ( dataflow == requiredDataflowDirection ) &&
238 (( communication == KSPIN_COMMUNICATION_SINK) ||
239 ( communication == KSPIN_COMMUNICATION_BOTH))
240 && ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
241 KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
242 || KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
243 KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
244 && KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
245 KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
246 {
247 KSMULTIPLE_ITEM* item = NULL;
248 if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError )
249 {
250 KSDATARANGE *dataRange = (KSDATARANGE*)(item+1);
251
252 for( i=0; i < item->Count; ++i ){
253
254 if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat)
255 || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0
256 || memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0
257 || ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 )
258 && ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) )
259 {
260 KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange;
261
262 /*
263 printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath );
264
265 if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 )
266 printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" );
267 else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 )
268 printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" );
269 else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 )
270 printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" );
271 else
272 printf( "\tspecifier: ?\n" );
273 */
274
275 /*
276 We assume that very high values for MaximumChannels are not useful and indicate
277 that the driver isn't prepared to tell us the real number of channels which it supports.
278 */
279 if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
280 result = (int)dataRangeAudio->MaximumChannels;
281 }
282
283 dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
284 }
285
286 PaUtil_FreeMemory( item );
287 }
288 }
289 }
290
291 CloseHandle( deviceHandle );
292 return result;
293 }

  ViewVC Help
Powered by ViewVC 1.1.22