PortAudio  2.0
pa_win_wasapi.h
Go to the documentation of this file.
1 #ifndef PA_WIN_WASAPI_H
2 #define PA_WIN_WASAPI_H
3 /*
4  * $Id: $
5  * PortAudio Portable Real-Time Audio Library
6  * WASAPI specific extensions
7  *
8  * Copyright (c) 1999-2018 Ross Bencina and Phil Burk
9  * Copyright (c) 2006-2010 David Viens
10  * Copyright (c) 2010-2018 Dmitry Kostjuchenko
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining
13  * a copy of this software and associated documentation files
14  * (the "Software"), to deal in the Software without restriction,
15  * including without limitation the rights to use, copy, modify, merge,
16  * publish, distribute, sublicense, and/or sell copies of the Software,
17  * and to permit persons to whom the Software is furnished to do so,
18  * subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be
21  * included in all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
27  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
28  * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30  */
31 
32 /*
33  * The text above constitutes the entire PortAudio license; however,
34  * the PortAudio community also makes the following non-binding requests:
35  *
36  * Any person wishing to distribute modifications to the Software is
37  * requested to send the modifications to the original developer so that
38  * they can be incorporated into the canonical version. It is also
39  * requested that these non-binding requests be included along with the
40  * license above.
41  */
42 
48 #include "portaudio.h"
49 #include "pa_win_waveformat.h"
50 
51 #ifdef __cplusplus
52 extern "C"
53 {
54 #endif /* __cplusplus */
55 
56 
57 /* Stream setup flags. */
58 typedef enum PaWasapiFlags
59 {
60  /* put WASAPI into exclusive mode */
61  paWinWasapiExclusive = (1 << 0),
62 
63  /* allow to skip internal PA processing completely */
64  paWinWasapiRedirectHostProcessor = (1 << 1),
65 
66  /* assign custom channel mask */
67  paWinWasapiUseChannelMask = (1 << 2),
68 
69  /* select non-Event driven method of data read/write
70  Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling
71  method can only provide 15-20ms latency. */
72  paWinWasapiPolling = (1 << 3),
73 
74  /* force custom thread priority setting, must be used if PaWasapiStreamInfo::threadPriority
75  is set to a custom value */
76  paWinWasapiThreadPriority = (1 << 4),
77 
78  /* force explicit sample format and do not allow PA to select suitable working format, API will
79  fail if provided sample format is not supported by audio hardware in Exclusive mode
80  or system mixer in Shared mode */
81  paWinWasapiExplicitSampleFormat = (1 << 5)
82 }
83 PaWasapiFlags;
84 #define paWinWasapiExclusive (paWinWasapiExclusive)
85 #define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)
86 #define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask)
87 #define paWinWasapiPolling (paWinWasapiPolling)
88 #define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
89 #define paWinWasapiExplicitSampleFormat (paWinWasapiExplicitSampleFormat)
90 
91 
92 /* Stream state.
93 
94  @note Multiple states can be united into a bitmask.
95  @see PaWasapiStreamStateCallback, PaWasapi_SetStreamStateHandler
96 */
97 typedef enum PaWasapiStreamState
98 {
99  /* state change was caused by the error:
100 
101  Example:
102  1) If thread execution stopped due to AUDCLNT_E_RESOURCES_INVALIDATED then state
103  value will contain paWasapiStreamStateError|paWasapiStreamStateThreadStop.
104  */
105  paWasapiStreamStateError = (1 << 0),
106 
107  /* processing thread is preparing to start execution */
108  paWasapiStreamStateThreadPrepare = (1 << 1),
109 
110  /* processing thread started execution (enters its loop) */
111  paWasapiStreamStateThreadStart = (1 << 2),
112 
113  /* processing thread stopped execution */
114  paWasapiStreamStateThreadStop = (1 << 3)
115 }
116 PaWasapiStreamState;
117 #define paWasapiStreamStateError (paWasapiStreamStateError)
118 #define paWasapiStreamStateThreadPrepare (paWasapiStreamStateThreadPrepare)
119 #define paWasapiStreamStateThreadStart (paWasapiStreamStateThreadStart)
120 #define paWasapiStreamStateThreadStop (paWasapiStreamStateThreadStop)
121 
122 
123 /* Host processor.
124 
125  Allows to skip internal PA processing completely. paWinWasapiRedirectHostProcessor flag
126  must be set to the PaWasapiStreamInfo::flags member in order to have host processor
127  redirected to this callback.
128 
129  Use with caution! inputFrames and outputFrames depend solely on final device setup.
130  To query max values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer.
131 */
132 typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames,
133  void *outputBuffer, long outputFrames, void *userData);
134 
135 
136 /* Stream state handler.
137 
138  @param pStream Pointer to PaStream object.
139  @param stateFlags State flags, a collection of values from PaWasapiStreamState enum.
140  @param errorId Error id provided by system API (HRESULT).
141  @param userData Pointer to user data.
142 
143  @see PaWasapiStreamState
144 */
145 typedef void (*PaWasapiStreamStateCallback) (PaStream *pStream, unsigned int stateFlags,
146  unsigned int errorId, void *pUserData);
147 
148 
149 /* Device role. */
150 typedef enum PaWasapiDeviceRole
151 {
152  eRoleRemoteNetworkDevice = 0,
153  eRoleSpeakers,
154  eRoleLineLevel,
155  eRoleHeadphones,
156  eRoleMicrophone,
157  eRoleHeadset,
158  eRoleHandset,
159  eRoleUnknownDigitalPassthrough,
160  eRoleSPDIF,
161  eRoleHDMI,
162  eRoleUnknownFormFactor
163 }
164 PaWasapiDeviceRole;
165 
166 
167 /* Jack connection type. */
168 typedef enum PaWasapiJackConnectionType
169 {
170  eJackConnTypeUnknown,
171  eJackConnType3Point5mm,
172  eJackConnTypeQuarter,
173  eJackConnTypeAtapiInternal,
174  eJackConnTypeRCA,
175  eJackConnTypeOptical,
176  eJackConnTypeOtherDigital,
177  eJackConnTypeOtherAnalog,
178  eJackConnTypeMultichannelAnalogDIN,
179  eJackConnTypeXlrProfessional,
180  eJackConnTypeRJ11Modem,
181  eJackConnTypeCombination
182 }
183 PaWasapiJackConnectionType;
184 
185 
186 /* Jack geometric location. */
187 typedef enum PaWasapiJackGeoLocation
188 {
189  eJackGeoLocUnk = 0,
190  eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
191  eJackGeoLocFront,
192  eJackGeoLocLeft,
193  eJackGeoLocRight,
194  eJackGeoLocTop,
195  eJackGeoLocBottom,
196  eJackGeoLocRearPanel,
197  eJackGeoLocRiser,
198  eJackGeoLocInsideMobileLid,
199  eJackGeoLocDrivebay,
200  eJackGeoLocHDMI,
201  eJackGeoLocOutsideMobileLid,
202  eJackGeoLocATAPI,
203  eJackGeoLocReserved5,
204  eJackGeoLocReserved6,
205 }
206 PaWasapiJackGeoLocation;
207 
208 
209 /* Jack general location. */
210 typedef enum PaWasapiJackGenLocation
211 {
212  eJackGenLocPrimaryBox = 0,
213  eJackGenLocInternal,
214  eJackGenLocSeparate,
215  eJackGenLocOther
216 }
217 PaWasapiJackGenLocation;
218 
219 
220 /* Jack's type of port. */
221 typedef enum PaWasapiJackPortConnection
222 {
223  eJackPortConnJack = 0,
224  eJackPortConnIntegratedDevice,
225  eJackPortConnBothIntegratedAndJack,
226  eJackPortConnUnknown
227 }
228 PaWasapiJackPortConnection;
229 
230 
231 /* Thread priority. */
233 {
234  eThreadPriorityNone = 0,
236  eThreadPriorityCapture,
237  eThreadPriorityDistribution,
238  eThreadPriorityGames,
239  eThreadPriorityPlayback,
241  eThreadPriorityWindowManager
242 }
244 
245 
246 /* Stream descriptor. */
248 {
249  unsigned long channelMapping;
250  unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */
251  PaWasapiJackConnectionType connectionType;
252  PaWasapiJackGeoLocation geoLocation;
253  PaWasapiJackGenLocation genLocation;
254  PaWasapiJackPortConnection portConnection;
255  unsigned int isConnected;
256 }
258 
259 
269 {
270  eAudioCategoryOther = 0,
271  eAudioCategoryCommunications = 3,
272  eAudioCategoryAlerts = 4,
273  eAudioCategorySoundEffects = 5,
274  eAudioCategoryGameEffects = 6,
275  eAudioCategoryGameMedia = 7,
276  eAudioCategoryGameChat = 8,
277  eAudioCategorySpeech = 9,
278  eAudioCategoryMovie = 10,
279  eAudioCategoryMedia = 11
280 }
282 
283 
292 {
296 }
298 
299 
300 /* Stream descriptor. */
301 typedef struct PaWasapiStreamInfo
302 {
303  unsigned long size;
305  unsigned long version;
307  unsigned long flags;
315  PaWinWaveFormatChannelMask channelMask;
316 
322  PaWasapiHostProcessorCallback hostProcessorOutput;
323  PaWasapiHostProcessorCallback hostProcessorInput;
324 
333 
339 
345 }
347 
348 
357 PaError PaWasapi_GetAudioClient( PaStream *pStream, void **pAudioClient, int bOutput );
358 
359 
371 
372 
388 int PaWasapi_GetDeviceCurrentFormat( PaStream *pStream, void *pFormat, unsigned int formatSize, int bOutput );
389 
390 
404 int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int formatSize, PaDeviceIndex device );
405 
406 
420 int PaWasapi_GetDeviceMixFormat( void *pFormat, unsigned int formatSize, PaDeviceIndex device );
421 
422 
430 int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex device );
431 
432 
446 PaError PaWasapi_ThreadPriorityBoost( void **pTask, PaWasapiThreadPriority priorityClass );
447 
448 
459 
460 
474 PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *pInput, unsigned int *pOutput );
475 
476 
490 PaError PaWasapi_GetJackCount( PaDeviceIndex device, int *pJackCount );
491 
492 
509 PaError PaWasapi_GetJackDescription( PaDeviceIndex device, int jackIndex, PaWasapiJackDescription *pJackDescription );
510 
511 
531 PaError PaWasapi_SetDefaultInterfaceId( unsigned short *pId, int bOutput );
532 
533 
542 PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCallback fnStateHandler, void *pUserData );
543 
544 
545 /*
546  IMPORTANT:
547 
548  WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
549  share modes.
550 
551  Exclusive Mode:
552 
553  Exclusive mode allows to deliver audio data directly to hardware bypassing
554  software mixing.
555  Exclusive mode is specified by 'paWinWasapiExclusive' flag.
556 
557  Callback Interface:
558 
559  Provides best audio quality with low latency. Callback interface is implemented in
560  two versions:
561 
562  1) Event-Driven:
563  This is the most powerful WASAPI implementation which provides glitch-free
564  audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
565  3 ms for HD Audio class audio chips. For the Shared mode latency can not be
566  lower than 20 ms.
567 
568  2) Poll-Driven:
569  Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
570  and provides latency at around 10-13ms. Polling must be used to overcome a system bug
571  under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply
572  times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug
573  does not exist in Vista x86 or Windows 7.
574  Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects
575  WOW64 bug and sets 'paWinWasapiPolling' automatically.
576 
577  Thread priority:
578 
579  Normally thread priority is set automatically and does not require modification. Although
580  if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority'
581  flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority
582  enum.
583 
584  Blocking Interface:
585 
586  Blocking interface is implemented but due to above described Poll-Driven method can not
587  deliver lowest possible latency. Specifying too low latency in Shared mode will result in
588  distorted audio although Exclusive mode adds stability.
589 
590  8.24 format:
591 
592  If paCustomFormat is specified as sample format then the implementation will understand it
593  as valid 24-bits inside 32-bit container (e.g. wBitsPerSample = 32, Samples.wValidBitsPerSample = 24).
594 
595  By using paCustomFormat there will be small optimization when samples are be copied
596  with Copy_24_To_24 by PA processor instead of conversion from packed 3-byte (24-bit) data
597  with Int24_To_Int32.
598 
599  Pa_IsFormatSupported:
600 
601  To check format with correct Share Mode (Exclusive/Shared) you must supply PaWasapiStreamInfo
602  with flags paWinWasapiExclusive set through member of PaStreamParameters::hostApiSpecificStreamInfo
603  structure.
604 
605  If paWinWasapiExplicitSampleFormat flag is provided then implementation will not try to select
606  suitable close format and will return an error instead of paFormatIsSupported. By specifying
607  paWinWasapiExplicitSampleFormat flag it is possible to find out what sample formats are
608  supported by Exclusive or Shared modes.
609 
610  Pa_OpenStream:
611 
612  To set desired Share Mode (Exclusive/Shared) you must supply
613  PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
614  PaStreamParameters::hostApiSpecificStreamInfo structure.
615 
616  Coding style for parameters and structure members of the public API:
617 
618  1) bXXX - boolean, [1 (TRUE), 0 (FALSE)]
619  2) pXXX - pointer
620  3) fnXXX - pointer to function
621  4) structure members are never prefixed with a type distinguisher
622 */
623 
624 #ifdef __cplusplus
625 }
626 #endif /* __cplusplus */
627 
628 #endif /* PA_WIN_WASAPI_H */