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
47
48#include "portaudio.h"
49#include "pa_win_waveformat.h"
50
51#ifdef __cplusplus
52extern "C"
53{
54#endif /* __cplusplus */
55
56
57/* Stream setup flags. */
58typedef 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 /* allow API to insert system-level channel matrix mixer and sample rate converter to allow
84 playback formats that do not match the current configured system settings.
85 this is in particular required for streams not matching the system mixer sample rate.
86 only applies in Shared mode. */
87 paWinWasapiAutoConvert = (1 << 6)
88}
89PaWasapiFlags;
90#define paWinWasapiExclusive (paWinWasapiExclusive)
91#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)
92#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask)
93#define paWinWasapiPolling (paWinWasapiPolling)
94#define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
95#define paWinWasapiExplicitSampleFormat (paWinWasapiExplicitSampleFormat)
96#define paWinWasapiAutoConvert (paWinWasapiAutoConvert)
97
98
99/* Stream state.
100
101 @note Multiple states can be united into a bitmask.
102 @see PaWasapiStreamStateCallback, PaWasapi_SetStreamStateHandler
103*/
104typedef enum PaWasapiStreamState
105{
106 /* state change was caused by the error:
107
108 Example:
109 1) If thread execution stopped due to AUDCLNT_E_RESOURCES_INVALIDATED then state
110 value will contain paWasapiStreamStateError|paWasapiStreamStateThreadStop.
111 */
112 paWasapiStreamStateError = (1 << 0),
113
114 /* processing thread is preparing to start execution */
115 paWasapiStreamStateThreadPrepare = (1 << 1),
116
117 /* processing thread started execution (enters its loop) */
118 paWasapiStreamStateThreadStart = (1 << 2),
119
120 /* processing thread stopped execution */
121 paWasapiStreamStateThreadStop = (1 << 3)
122}
123PaWasapiStreamState;
124#define paWasapiStreamStateError (paWasapiStreamStateError)
125#define paWasapiStreamStateThreadPrepare (paWasapiStreamStateThreadPrepare)
126#define paWasapiStreamStateThreadStart (paWasapiStreamStateThreadStart)
127#define paWasapiStreamStateThreadStop (paWasapiStreamStateThreadStop)
128
129
130/* Host processor.
131
132 Allows to skip internal PA processing completely. paWinWasapiRedirectHostProcessor flag
133 must be set to the PaWasapiStreamInfo::flags member in order to have host processor
134 redirected to this callback.
135
136 Use with caution! inputFrames and outputFrames depend solely on final device setup.
137 To query max values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer.
138*/
139typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames,
140 void *outputBuffer, long outputFrames, void *userData);
141
142
143/* Stream state handler.
144
145 @param pStream Pointer to PaStream object.
146 @param stateFlags State flags, a collection of values from PaWasapiStreamState enum.
147 @param errorId Error id provided by system API (HRESULT).
148 @param userData Pointer to user data.
149
150 @see PaWasapiStreamState
151*/
152typedef void (*PaWasapiStreamStateCallback) (PaStream *pStream, unsigned int stateFlags,
153 unsigned int errorId, void *pUserData);
154
155
156/* Device role. */
157typedef enum PaWasapiDeviceRole
158{
159 eRoleRemoteNetworkDevice = 0,
160 eRoleSpeakers,
161 eRoleLineLevel,
162 eRoleHeadphones,
163 eRoleMicrophone,
164 eRoleHeadset,
165 eRoleHandset,
166 eRoleUnknownDigitalPassthrough,
167 eRoleSPDIF,
168 eRoleHDMI,
169 eRoleUnknownFormFactor
170}
171PaWasapiDeviceRole;
172
173
174/* Jack connection type. */
175typedef enum PaWasapiJackConnectionType
176{
177 eJackConnTypeUnknown,
178 eJackConnType3Point5mm,
179 eJackConnTypeQuarter,
180 eJackConnTypeAtapiInternal,
181 eJackConnTypeRCA,
182 eJackConnTypeOptical,
183 eJackConnTypeOtherDigital,
184 eJackConnTypeOtherAnalog,
185 eJackConnTypeMultichannelAnalogDIN,
186 eJackConnTypeXlrProfessional,
187 eJackConnTypeRJ11Modem,
188 eJackConnTypeCombination
189}
190PaWasapiJackConnectionType;
191
192
193/* Jack geometric location. */
194typedef enum PaWasapiJackGeoLocation
195{
196 eJackGeoLocUnk = 0,
197 eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
198 eJackGeoLocFront,
199 eJackGeoLocLeft,
200 eJackGeoLocRight,
201 eJackGeoLocTop,
202 eJackGeoLocBottom,
203 eJackGeoLocRearPanel,
204 eJackGeoLocRiser,
205 eJackGeoLocInsideMobileLid,
206 eJackGeoLocDrivebay,
207 eJackGeoLocHDMI,
208 eJackGeoLocOutsideMobileLid,
209 eJackGeoLocATAPI,
210 eJackGeoLocReserved5,
211 eJackGeoLocReserved6,
212}
213PaWasapiJackGeoLocation;
214
215
216/* Jack general location. */
217typedef enum PaWasapiJackGenLocation
218{
219 eJackGenLocPrimaryBox = 0,
220 eJackGenLocInternal,
221 eJackGenLocSeparate,
222 eJackGenLocOther
223}
224PaWasapiJackGenLocation;
225
226
227/* Jack's type of port. */
228typedef enum PaWasapiJackPortConnection
229{
230 eJackPortConnJack = 0,
231 eJackPortConnIntegratedDevice,
232 eJackPortConnBothIntegratedAndJack,
233 eJackPortConnUnknown
234}
235PaWasapiJackPortConnection;
236
237
238/* Thread priority. */
240{
241 eThreadPriorityNone = 0,
243 eThreadPriorityCapture,
244 eThreadPriorityDistribution,
245 eThreadPriorityGames,
246 eThreadPriorityPlayback,
248 eThreadPriorityWindowManager
249}
251
252
253/* Stream descriptor. */
255{
256 unsigned long channelMapping;
257 unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */
258 PaWasapiJackConnectionType connectionType;
259 PaWasapiJackGeoLocation geoLocation;
260 PaWasapiJackGenLocation genLocation;
261 PaWasapiJackPortConnection portConnection;
262 unsigned int isConnected;
263}
265
266
276{
277 eAudioCategoryOther = 0,
278 eAudioCategoryCommunications = 3,
279 eAudioCategoryAlerts = 4,
280 eAudioCategorySoundEffects = 5,
281 eAudioCategoryGameEffects = 6,
282 eAudioCategoryGameMedia = 7,
283 eAudioCategoryGameChat = 8,
284 eAudioCategorySpeech = 9,
285 eAudioCategoryMovie = 10,
286 eAudioCategoryMedia = 11
287}
289
290
305
306
307/* Stream descriptor. */
308typedef struct PaWasapiStreamInfo
309{
310 unsigned long size;
312 unsigned long version;
313
314 unsigned long flags;
315
322 PaWinWaveFormatChannelMask channelMask;
323
329 PaWasapiHostProcessorCallback hostProcessorOutput;
330 PaWasapiHostProcessorCallback hostProcessorInput;
331
340
346
352}
354
355
364PaError PaWasapi_GetAudioClient( PaStream *pStream, void **pAudioClient, int bOutput );
365
366
378
379
395int PaWasapi_GetDeviceCurrentFormat( PaStream *pStream, void *pFormat, unsigned int formatSize, int bOutput );
396
397
411int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int formatSize, PaDeviceIndex device );
412
413
427int PaWasapi_GetDeviceMixFormat( void *pFormat, unsigned int formatSize, PaDeviceIndex device );
428
429
437int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex device );
438
439
447PaError PaWasapi_GetIMMDevice( PaDeviceIndex device, void **pIMMDevice );
448
449
464
465
476
477
491PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *pInput, unsigned int *pOutput );
492
493
507PaError PaWasapi_GetJackCount( PaDeviceIndex device, int *pJackCount );
508
509
527
528
537PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCallback fnStateHandler, void *pUserData );
538
539
567PaError PaWasapiWinrt_SetDefaultDeviceId( const unsigned short *pId, int bOutput );
568
569
604PaError PaWasapiWinrt_PopulateDeviceList( const unsigned short **pId, const unsigned short **pName,
605 const PaWasapiDeviceRole *pRole, unsigned int count, int bOutput );
606
607
608/*
609 IMPORTANT:
610
611 WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
612 share modes.
613
614 Exclusive Mode:
615
616 Exclusive mode allows to deliver audio data directly to hardware bypassing
617 software mixing.
618 Exclusive mode is specified by 'paWinWasapiExclusive' flag.
619
620 Callback Interface:
621
622 Provides best audio quality with low latency. Callback interface is implemented in
623 two versions:
624
625 1) Event-Driven:
626 This is the most powerful WASAPI implementation which provides glitch-free
627 audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is
628 3 ms for HD Audio class audio chips. For the Shared mode latency can not be
629 lower than 20 ms.
630
631 2) Poll-Driven:
632 Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
633 and provides latency at around 10-13ms. Polling must be used to overcome a system bug
634 under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply
635 times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug
636 does not exist in Vista x86 or Windows 7.
637 Polling can be setup by specifying 'paWinWasapiPolling' flag. Our WASAPI implementation detects
638 WOW64 bug and sets 'paWinWasapiPolling' automatically.
639
640 Thread priority:
641
642 Normally thread priority is set automatically and does not require modification. Although
643 if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority'
644 flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority
645 enum.
646
647 Blocking Interface:
648
649 Blocking interface is implemented but due to above described Poll-Driven method can not
650 deliver lowest possible latency. Specifying too low latency in Shared mode will result in
651 distorted audio although Exclusive mode adds stability.
652
653 8.24 format:
654
655 If paCustomFormat is specified as sample format then the implementation will understand it
656 as valid 24-bits inside 32-bit container (e.g. wBitsPerSample = 32, Samples.wValidBitsPerSample = 24).
657
658 By using paCustomFormat there will be small optimization when samples are be copied
659 with Copy_24_To_24 by PA processor instead of conversion from packed 3-byte (24-bit) data
660 with Int24_To_Int32.
661
662 Pa_IsFormatSupported:
663
664 To check format with correct Share Mode (Exclusive/Shared) you must supply PaWasapiStreamInfo
665 with flags paWinWasapiExclusive set through member of PaStreamParameters::hostApiSpecificStreamInfo
666 structure.
667
668 If paWinWasapiExplicitSampleFormat flag is provided then implementation will not try to select
669 suitable close format and will return an error instead of paFormatIsSupported. By specifying
670 paWinWasapiExplicitSampleFormat flag it is possible to find out what sample formats are
671 supported by Exclusive or Shared modes.
672
673 Pa_OpenStream:
674
675 To set desired Share Mode (Exclusive/Shared) you must supply
676 PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
677 PaStreamParameters::hostApiSpecificStreamInfo structure.
678
679 Coding style for parameters and structure members of the public API:
680
681 1) bXXX - boolean, [1 (TRUE), 0 (FALSE)]
682 2) pXXX - pointer
683 3) fnXXX - pointer to function
684 4) structure members are never prefixed with a type distinguisher
685
686
687 UWP/WinRT:
688
689 This platform has number of limitations which do not allow to enumerate audio devices without
690 an additional external help. Enumeration is possible though from C++/CX, check the related API
691 Windows::Devices::Enumeration::DeviceInformation::FindAllAsync().
692
693 The main limitation is an absence of the device enumeration from inside the PA's implementation.
694 This problem can be solved by using the following functions:
695
696 PaWasapiWinrt_SetDefaultDeviceId() - to set default input/output device,
697 PaWasapiWinrt_PopulateDeviceList() - to populate device list with devices.
698
699 Here is an example of populating the device list which can also be updated dynamically depending on
700 whether device was removed from or added to the system:
701
702 ----------------
703
704 std::vector<const UINT16 *> ids, names;
705 std::vector<PaWasapiDeviceRole> role;
706
707 ids.resize(count);
708 names.resize(count);
709 role.resize(count);
710
711 for (UINT32 i = 0; i < count; ++i)
712 {
713 ids[i] = (const UINT16 *)device_ids[i].c_str();
714 names[i] = (const UINT16 *)device_names[i].c_str();
715 role[i] = eRoleUnknownFormFactor;
716 }
717
718 PaWasapiWinrt_SetDefaultDeviceId((const UINT16 *)default_device_id.c_str(), !capture);
719 PaWasapiWinrt_PopulateDeviceList(ids.data(), names.data(), role.data(), count, !capture);
720 PaWasapi_UpdateDeviceList();
721
722 ----------------
723*/
724
725#ifdef __cplusplus
726}
727#endif /* __cplusplus */
728
729#endif /* PA_WIN_WASAPI_H */
PaError PaWasapi_GetAudioClient(PaStream *pStream, void **pAudioClient, int bOutput)
int PaWasapi_GetDeviceDefaultFormat(void *pFormat, unsigned int formatSize, PaDeviceIndex device)
PaWasapiThreadPriority
@ eThreadPriorityAudio
Default for Shared mode.
@ eThreadPriorityProAudio
Default for Exclusive mode.
PaWasapiStreamOption
@ eStreamOptionRaw
bypass WASAPI Audio Engine DSP effects, supported since Windows 8.1
@ eStreamOptionNone
default
@ eStreamOptionMatchFormat
force WASAPI Audio Engine into a stream format, supported since Windows 10
PaError PaWasapi_SetStreamStateHandler(PaStream *pStream, PaWasapiStreamStateCallback fnStateHandler, void *pUserData)
PaError PaWasapi_GetIMMDevice(PaDeviceIndex device, void **pIMMDevice)
PaError PaWasapiWinrt_PopulateDeviceList(const unsigned short **pId, const unsigned short **pName, const PaWasapiDeviceRole *pRole, unsigned int count, int bOutput)
PaError PaWasapiWinrt_SetDefaultDeviceId(const unsigned short *pId, int bOutput)
int PaWasapi_GetDeviceMixFormat(void *pFormat, unsigned int formatSize, PaDeviceIndex device)
PaError PaWasapi_GetFramesPerHostBuffer(PaStream *pStream, unsigned int *pInput, unsigned int *pOutput)
PaError PaWasapi_ThreadPriorityRevert(void *pTask)
int PaWasapi_GetDeviceRole(PaDeviceIndex device)
PaError PaWasapi_ThreadPriorityBoost(void **pTask, PaWasapiThreadPriority priorityClass)
PaWasapiStreamCategory
int PaWasapi_GetDeviceCurrentFormat(PaStream *pStream, void *pFormat, unsigned int formatSize, int bOutput)
PaError PaWasapi_GetJackDescription(PaDeviceIndex device, int jackIndex, PaWasapiJackDescription *pJackDescription)
PaError PaWasapi_UpdateDeviceList()
PaError PaWasapi_GetJackCount(PaDeviceIndex device, int *pJackCount)
Windows specific PortAudio API extension and utilities header file.
The portable PortAudio API.
void PaStream
Definition portaudio.h:635
int PaError
Definition portaudio.h:121
PaHostApiTypeId
Definition portaudio.h:276
int PaDeviceIndex
Definition portaudio.h:212
PaWasapiHostProcessorCallback hostProcessorOutput
unsigned long version
PaWinWaveFormatChannelMask channelMask
PaWasapiStreamCategory streamCategory
PaWasapiThreadPriority threadPriority
unsigned long flags
PaHostApiTypeId hostApiType
PaWasapiStreamOption streamOption
unsigned long size