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-2022 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
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 /* use Polling method (Event method is the default, see details in the IMPORTANT notes) */
70 paWinWasapiPolling = (1 << 3),
71
72 /* force custom thread priority setting, must be used if PaWasapiStreamInfo::threadPriority
73 is set to a custom value */
74 paWinWasapiThreadPriority = (1 << 4),
75
76 /* force explicit sample format and do not allow PA to select suitable working format, API will
77 fail if provided sample format is not supported by audio hardware in Exclusive mode
78 or system mixer in Shared mode */
79 paWinWasapiExplicitSampleFormat = (1 << 5),
80
81 /* allow API to insert system-level channel matrix mixer and sample rate converter to allow
82 playback formats that do not match the current configured system settings.
83 this is in particular required for streams not matching the system mixer sample rate.
84 only applies in Shared mode. */
85 paWinWasapiAutoConvert = (1 << 6),
86
87 /* use Passthrough mode for sending encoded audio data in PCM containers to the audio device,
88 refer to Microsoft documentation "Representing Formats for IEC 61937 Transmissions" for more
89 details about data representation and stream configuration */
90 paWinWasapiPassthrough = (1 << 7),
91}
92PaWasapiFlags;
93#define paWinWasapiExclusive (paWinWasapiExclusive)
94#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor)
95#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask)
96#define paWinWasapiPolling (paWinWasapiPolling)
97#define paWinWasapiThreadPriority (paWinWasapiThreadPriority)
98#define paWinWasapiExplicitSampleFormat (paWinWasapiExplicitSampleFormat)
99#define paWinWasapiAutoConvert (paWinWasapiAutoConvert)
100#define paWinWasapiPassthrough (paWinWasapiPassthrough)
101
102
103/* Stream state.
104
105 @note Multiple states can be united into a bitmask.
106 @see PaWasapiStreamStateCallback, PaWasapi_SetStreamStateHandler
107*/
108typedef enum PaWasapiStreamState
109{
110 /* state change was caused by the error:
111
112 Example:
113 1) If thread execution stopped due to AUDCLNT_E_RESOURCES_INVALIDATED then state
114 value will contain paWasapiStreamStateError|paWasapiStreamStateThreadStop.
115 */
116 paWasapiStreamStateError = (1 << 0),
117
118 /* processing thread is preparing to start execution */
119 paWasapiStreamStateThreadPrepare = (1 << 1),
120
121 /* processing thread started execution (enters its loop) */
122 paWasapiStreamStateThreadStart = (1 << 2),
123
124 /* processing thread stopped execution */
125 paWasapiStreamStateThreadStop = (1 << 3)
126}
127PaWasapiStreamState;
128#define paWasapiStreamStateError (paWasapiStreamStateError)
129#define paWasapiStreamStateThreadPrepare (paWasapiStreamStateThreadPrepare)
130#define paWasapiStreamStateThreadStart (paWasapiStreamStateThreadStart)
131#define paWasapiStreamStateThreadStop (paWasapiStreamStateThreadStop)
132
133
134/* Host processor.
135
136 Allows to skip internal PA processing completely. paWinWasapiRedirectHostProcessor flag
137 must be set to the PaWasapiStreamInfo::flags member in order to have host processor
138 redirected to this callback.
139
140 Use with caution! inputFrames and outputFrames depend solely on final device setup.
141 To query max values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer.
142*/
143typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames,
144 void *outputBuffer, long outputFrames, void *userData);
145
146
147/* Stream state handler.
148
149 @param pStream Pointer to PaStream object.
150 @param stateFlags State flags, a collection of values from PaWasapiStreamState enum.
151 @param errorId Error id provided by system API (HRESULT).
152 @param userData Pointer to user data.
153
154 @see PaWasapiStreamState
155*/
156typedef void (*PaWasapiStreamStateCallback) (PaStream *pStream, unsigned int stateFlags,
157 unsigned int errorId, void *pUserData);
158
159
160/* Device role. */
161typedef enum PaWasapiDeviceRole
162{
163 eRoleRemoteNetworkDevice = 0,
164 eRoleSpeakers,
165 eRoleLineLevel,
166 eRoleHeadphones,
167 eRoleMicrophone,
168 eRoleHeadset,
169 eRoleHandset,
170 eRoleUnknownDigitalPassthrough,
171 eRoleSPDIF,
172 eRoleHDMI,
173 eRoleUnknownFormFactor
174}
175PaWasapiDeviceRole;
176
177
178/* Jack connection type. */
179typedef enum PaWasapiJackConnectionType
180{
181 eJackConnTypeUnknown,
182 eJackConnType3Point5mm,
183 eJackConnTypeQuarter,
184 eJackConnTypeAtapiInternal,
185 eJackConnTypeRCA,
186 eJackConnTypeOptical,
187 eJackConnTypeOtherDigital,
188 eJackConnTypeOtherAnalog,
189 eJackConnTypeMultichannelAnalogDIN,
190 eJackConnTypeXlrProfessional,
191 eJackConnTypeRJ11Modem,
192 eJackConnTypeCombination
193}
194PaWasapiJackConnectionType;
195
196
197/* Jack geometric location. */
198typedef enum PaWasapiJackGeoLocation
199{
200 eJackGeoLocUnk = 0,
201 eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
202 eJackGeoLocFront,
203 eJackGeoLocLeft,
204 eJackGeoLocRight,
205 eJackGeoLocTop,
206 eJackGeoLocBottom,
207 eJackGeoLocRearPanel,
208 eJackGeoLocRiser,
209 eJackGeoLocInsideMobileLid,
210 eJackGeoLocDrivebay,
211 eJackGeoLocHDMI,
212 eJackGeoLocOutsideMobileLid,
213 eJackGeoLocATAPI,
214 eJackGeoLocReserved5,
215 eJackGeoLocReserved6,
216}
217PaWasapiJackGeoLocation;
218
219
220/* Jack general location. */
221typedef enum PaWasapiJackGenLocation
222{
223 eJackGenLocPrimaryBox = 0,
224 eJackGenLocInternal,
225 eJackGenLocSeparate,
226 eJackGenLocOther
227}
228PaWasapiJackGenLocation;
229
230
231/* Jack's type of port. */
232typedef enum PaWasapiJackPortConnection
233{
234 eJackPortConnJack = 0,
235 eJackPortConnIntegratedDevice,
236 eJackPortConnBothIntegratedAndJack,
237 eJackPortConnUnknown
238}
239PaWasapiJackPortConnection;
240
241
242/* Thread priority. */
244{
245 eThreadPriorityNone = 0,
247 eThreadPriorityCapture,
248 eThreadPriorityDistribution,
249 eThreadPriorityGames,
250 eThreadPriorityPlayback,
252 eThreadPriorityWindowManager
253}
255
256
257/* Stream descriptor. */
259{
260 unsigned long channelMapping;
261 unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */
262 PaWasapiJackConnectionType connectionType;
263 PaWasapiJackGeoLocation geoLocation;
264 PaWasapiJackGenLocation genLocation;
265 PaWasapiJackPortConnection portConnection;
266 unsigned int isConnected;
267}
269
270
280{
281 eAudioCategoryOther = 0,
282 eAudioCategoryCommunications = 3,
283 eAudioCategoryAlerts = 4,
284 eAudioCategorySoundEffects = 5,
285 eAudioCategoryGameEffects = 6,
286 eAudioCategoryGameMedia = 7,
287 eAudioCategoryGameChat = 8,
288 eAudioCategorySpeech = 9,
289 eAudioCategoryMovie = 10,
290 eAudioCategoryMedia = 11
291}
293
294
309
310
321{
322 ePassthroughFormatPcmIec60958 = 0x00000000,
323 ePassthroughFormatDolbyDigital = 0x00920000,
324 ePassthroughFormatMpeg1 = 0x00030cea,
325 ePassthroughFormatMpeg3 = 0x00040cea,
326 ePassthroughFormatMpeg2 = 0x00050cea,
327 ePassthroughFormatAac = 0x00060cea,
328 ePassthroughFormatDts = 0x00080cea,
329 ePassthroughFormatDolbyDigitalPlus = 0x000a0cea,
330 ePassthroughFormatDolbyDigitalPlusAtmos = 0x010a0cea,
331 ePassthroughFormatDtsHd = 0x000b0cea,
332 ePassthroughFormatDtsXE1 = 0x010b0cea,
333 ePassthroughFormatDtsXE2 = 0x030b0cea,
334 ePassthroughFormatDolbyMlp = 0x000c0cea,
335 ePassthroughFormatDolbyMat20 = 0x010c0cea,
336 ePassthroughFormatDolbyMat21 = 0x030c0cea,
337 ePassthroughFormatWmaPro = 0x01640000,
338 ePassthroughFormatAtrac = 0x00080cea,
339 ePassthroughFormatOneBitAudio = 0x00090cea,
340 ePassthroughFormatDst = 0x000d0cea,
341}
343
344
357{
359 unsigned int encodedSamplesPerSec;
360 unsigned int encodedChannelCount;
361 unsigned int averageBytesPerSec;
362}
364
365
366/* Stream descriptor. */
367typedef struct PaWasapiStreamInfo
368{
369 unsigned long size;
371 unsigned long version;
373 unsigned long flags;
381 PaWinWaveFormatChannelMask channelMask;
382
388 PaWasapiHostProcessorCallback hostProcessorOutput;
389 PaWasapiHostProcessorCallback hostProcessorInput;
390
399
405
411
418}
420
421
430PaError PaWasapi_GetAudioClient( PaStream *pStream, void **pAudioClient, int bOutput );
431
432
444
445
461int PaWasapi_GetDeviceCurrentFormat( PaStream *pStream, void *pFormat, unsigned int formatSize, int bOutput );
462
463
477int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int formatSize, PaDeviceIndex device );
478
479
493int PaWasapi_GetDeviceMixFormat( void *pFormat, unsigned int formatSize, PaDeviceIndex device );
494
495
503int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex device );
504
505
513PaError PaWasapi_GetIMMDevice( PaDeviceIndex device, void **pIMMDevice );
514
515
528
529
544
545
556
557
571PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *pInput, unsigned int *pOutput );
572
573
587PaError PaWasapi_GetJackCount( PaDeviceIndex device, int *pJackCount );
588
589
607
608
617PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCallback fnStateHandler, void *pUserData );
618
619
647PaError PaWasapiWinrt_SetDefaultDeviceId( const unsigned short *pId, int bOutput );
648
649
684PaError PaWasapiWinrt_PopulateDeviceList( const unsigned short **pId, const unsigned short **pName,
685 const PaWasapiDeviceRole *pRole, unsigned int count, int bOutput );
686
687
688/*
689 IMPORTANT:
690
691 WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive
692 share modes.
693
694 Exclusive Mode:
695
696 Exclusive mode allows to deliver audio data directly to hardware bypassing
697 software mixing.
698 Exclusive mode is specified by 'paWinWasapiExclusive' flag.
699
700 Callback Interface:
701
702 Provides best audio quality with low latency. Callback interface is implemented in
703 two versions:
704
705 1) Event-driven:
706 It is the most powerful data processing method which provides glitch-free audio with
707 around 3 ms latency in Exclusive mode. Lowest possible latency for this mode is
708 3 ms for HD Audio class audio chips. For the Shared mode latency can not be
709 lower than 20 ms. This method consumes slightly less CPU in comparison to Polling.
710 It is the default processing method unless 'paWinWasapiPolling' is specified.
711
712 2) Poll-driven:
713 Polling is an alternative to Event-driven processing. Due to its nature Polling consumes
714 slightly more CPU. This method is less efficient than Event-driven and its lowest possible
715 latency is around 10-13 ms.
716 Note: Newer Windows versions (for example 11) allow to achieve similar to Event-driven
717 low latency.
718 Note: Polling must be used to overcome system bug of Windows Vista (x64) when application
719 is WOW64 (32-bit process running on 64-bit OS) that results in WASAPI callback timeout if
720 Event-driven method is selected (event handle is never signalled on buffer completion).
721 This WOW64 bug does not exist in Windows Vista (x86) or Windows 7 or newer Windows versions.
722 Polling can be activated by specifying 'paWinWasapiPolling' flag. Our implementation
723 detects WOW64 bug and sets 'paWinWasapiPolling' automatically.
724
725 Thread priority:
726
727 Normally thread priority is set automatically and does not require modification. Although
728 if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority'
729 flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority
730 enum.
731
732 Blocking Interface:
733
734 Blocking interface is implemented but due to above described Poll-Driven method can not
735 deliver lowest possible latency. Specifying too low latency in Shared mode will result in
736 distorted audio although Exclusive mode adds stability.
737
738 8.24 format:
739
740 If paCustomFormat is specified as sample format then the implementation will understand it
741 as valid 24-bits inside 32-bit container (e.g. wBitsPerSample = 32, Samples.wValidBitsPerSample = 24).
742
743 By using paCustomFormat there will be small optimization when samples are be copied
744 with Copy_24_To_24 by PA processor instead of conversion from packed 3-byte (24-bit) data
745 with Int24_To_Int32.
746
747 Pa_IsFormatSupported:
748
749 To check format with correct Share Mode (Exclusive/Shared) you must supply PaWasapiStreamInfo
750 with flags paWinWasapiExclusive set through member of PaStreamParameters::hostApiSpecificStreamInfo
751 structure.
752
753 If paWinWasapiExplicitSampleFormat flag is provided then implementation will not try to select
754 suitable close format and will return an error instead of paFormatIsSupported. By specifying
755 paWinWasapiExplicitSampleFormat flag it is possible to find out what sample formats are
756 supported by Exclusive or Shared modes.
757
758 Pa_OpenStream:
759
760 To set desired Share Mode (Exclusive/Shared) you must supply
761 PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of
762 PaStreamParameters::hostApiSpecificStreamInfo structure.
763
764 Coding style for parameters and structure members of the public API:
765
766 1) bXXX - boolean, [1 (TRUE), 0 (FALSE)]
767 2) pXXX - pointer
768 3) fnXXX - pointer to function
769 4) structure members are never prefixed with a type distinguisher
770
771
772 UWP/WinRT:
773
774 This platform has number of limitations which do not allow to enumerate audio devices without
775 an additional external help. Enumeration is possible though from C++/CX, check the related API
776 Windows::Devices::Enumeration::DeviceInformation::FindAllAsync().
777
778 The main limitation is an absence of the device enumeration from inside the PA's implementation.
779 This problem can be solved by using the following functions:
780
781 PaWasapiWinrt_SetDefaultDeviceId() - to set default input/output device,
782 PaWasapiWinrt_PopulateDeviceList() - to populate device list with devices.
783
784 Here is an example of populating the device list which can also be updated dynamically depending on
785 whether device was removed from or added to the system:
786
787 ----------------
788
789 std::vector<const UINT16 *> ids, names;
790 std::vector<PaWasapiDeviceRole> role;
791
792 ids.resize(count);
793 names.resize(count);
794 role.resize(count);
795
796 for (UINT32 i = 0; i < count; ++i)
797 {
798 ids[i] = (const UINT16 *)device_ids[i].c_str();
799 names[i] = (const UINT16 *)device_names[i].c_str();
800 role[i] = eRoleUnknownFormFactor;
801 }
802
803 PaWasapiWinrt_SetDefaultDeviceId((const UINT16 *)default_device_id.c_str(), !capture);
804 PaWasapiWinrt_PopulateDeviceList(ids.data(), names.data(), role.data(), count, !capture);
805 PaWasapi_UpdateDeviceList();
806
807 ----------------
808*/
809
810#ifdef __cplusplus
811}
812#endif /* __cplusplus */
813
814#endif /* PA_WIN_WASAPI_H */
PaError PaWasapi_GetAudioClient(PaStream *pStream, void **pAudioClient, int bOutput)
PaWasapiPassthroughFormat
int PaWasapi_GetDeviceDefaultFormat(void *pFormat, unsigned int formatSize, PaDeviceIndex device)
int PaWasapi_IsLoopback(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)
struct PaWasapiStreamPassthrough PaWasapiStreamPassthrough
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:644
int PaError
Definition portaudio.h:122
PaHostApiTypeId
Definition portaudio.h:278
int PaDeviceIndex
Definition portaudio.h:214
PaWasapiHostProcessorCallback hostProcessorOutput
unsigned long version
PaWinWaveFormatChannelMask channelMask
PaWasapiStreamCategory streamCategory
PaWasapiThreadPriority threadPriority
unsigned long flags
PaWasapiStreamPassthrough passthrough
PaHostApiTypeId hostApiType
PaWasapiStreamOption streamOption
unsigned long size