Chris@39: #ifndef PA_WIN_WASAPI_H Chris@39: #define PA_WIN_WASAPI_H Chris@39: /* Chris@39: * $Id: $ Chris@39: * PortAudio Portable Real-Time Audio Library Chris@39: * DirectSound specific extensions Chris@39: * Chris@39: * Copyright (c) 1999-2007 Ross Bencina and Phil Burk Chris@39: * Chris@39: * Permission is hereby granted, free of charge, to any person obtaining Chris@39: * a copy of this software and associated documentation files Chris@39: * (the "Software"), to deal in the Software without restriction, Chris@39: * including without limitation the rights to use, copy, modify, merge, Chris@39: * publish, distribute, sublicense, and/or sell copies of the Software, Chris@39: * and to permit persons to whom the Software is furnished to do so, Chris@39: * subject to the following conditions: Chris@39: * Chris@39: * The above copyright notice and this permission notice shall be Chris@39: * included in all copies or substantial portions of the Software. Chris@39: * Chris@39: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, Chris@39: * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF Chris@39: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. Chris@39: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR Chris@39: * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF Chris@39: * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION Chris@39: * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Chris@39: */ Chris@39: Chris@39: /* Chris@39: * The text above constitutes the entire PortAudio license; however, Chris@39: * the PortAudio community also makes the following non-binding requests: Chris@39: * Chris@39: * Any person wishing to distribute modifications to the Software is Chris@39: * requested to send the modifications to the original developer so that Chris@39: * they can be incorporated into the canonical version. It is also Chris@39: * requested that these non-binding requests be included along with the Chris@39: * license above. Chris@39: */ Chris@39: Chris@39: /** @file Chris@39: @ingroup public_header Chris@39: @brief WASAPI-specific PortAudio API extension header file. Chris@39: */ Chris@39: Chris@39: #include "portaudio.h" Chris@39: #include "pa_win_waveformat.h" Chris@39: Chris@39: #ifdef __cplusplus Chris@39: extern "C" Chris@39: { Chris@39: #endif /* __cplusplus */ Chris@39: Chris@39: Chris@39: /* Setup flags */ Chris@39: typedef enum PaWasapiFlags Chris@39: { Chris@39: /* puts WASAPI into exclusive mode */ Chris@39: paWinWasapiExclusive = (1 << 0), Chris@39: Chris@39: /* allows to skip internal PA processing completely */ Chris@39: paWinWasapiRedirectHostProcessor = (1 << 1), Chris@39: Chris@39: /* assigns custom channel mask */ Chris@39: paWinWasapiUseChannelMask = (1 << 2), Chris@39: Chris@39: /* selects non-Event driven method of data read/write Chris@39: Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling Chris@39: method can only provide 15-20ms latency. */ Chris@39: paWinWasapiPolling = (1 << 3), Chris@39: Chris@39: /* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority Chris@39: is set to custom value. */ Chris@39: paWinWasapiThreadPriority = (1 << 4) Chris@39: } Chris@39: PaWasapiFlags; Chris@39: #define paWinWasapiExclusive (paWinWasapiExclusive) Chris@39: #define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor) Chris@39: #define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask) Chris@39: #define paWinWasapiPolling (paWinWasapiPolling) Chris@39: #define paWinWasapiThreadPriority (paWinWasapiThreadPriority) Chris@39: Chris@39: Chris@39: /* Host processor. Allows to skip internal PA processing completely. Chris@39: You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member Chris@39: in order to have host processor redirected to your callback. Chris@39: Use with caution! inputFrames and outputFrames depend solely on final device setup. Chris@39: To query maximal values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer. Chris@39: */ Chris@39: typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames, Chris@39: void *outputBuffer, long outputFrames, Chris@39: void *userData); Chris@39: Chris@39: /* Device role */ Chris@39: typedef enum PaWasapiDeviceRole Chris@39: { Chris@39: eRoleRemoteNetworkDevice = 0, Chris@39: eRoleSpeakers, Chris@39: eRoleLineLevel, Chris@39: eRoleHeadphones, Chris@39: eRoleMicrophone, Chris@39: eRoleHeadset, Chris@39: eRoleHandset, Chris@39: eRoleUnknownDigitalPassthrough, Chris@39: eRoleSPDIF, Chris@39: eRoleHDMI, Chris@39: eRoleUnknownFormFactor Chris@39: } Chris@39: PaWasapiDeviceRole; Chris@39: Chris@39: Chris@39: /* Jack connection type */ Chris@39: typedef enum PaWasapiJackConnectionType Chris@39: { Chris@39: eJackConnTypeUnknown, Chris@39: eJackConnType3Point5mm, Chris@39: eJackConnTypeQuarter, Chris@39: eJackConnTypeAtapiInternal, Chris@39: eJackConnTypeRCA, Chris@39: eJackConnTypeOptical, Chris@39: eJackConnTypeOtherDigital, Chris@39: eJackConnTypeOtherAnalog, Chris@39: eJackConnTypeMultichannelAnalogDIN, Chris@39: eJackConnTypeXlrProfessional, Chris@39: eJackConnTypeRJ11Modem, Chris@39: eJackConnTypeCombination Chris@39: } Chris@39: PaWasapiJackConnectionType; Chris@39: Chris@39: Chris@39: /* Jack geometric location */ Chris@39: typedef enum PaWasapiJackGeoLocation Chris@39: { Chris@39: eJackGeoLocUnk = 0, Chris@39: eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */ Chris@39: eJackGeoLocFront, Chris@39: eJackGeoLocLeft, Chris@39: eJackGeoLocRight, Chris@39: eJackGeoLocTop, Chris@39: eJackGeoLocBottom, Chris@39: eJackGeoLocRearPanel, Chris@39: eJackGeoLocRiser, Chris@39: eJackGeoLocInsideMobileLid, Chris@39: eJackGeoLocDrivebay, Chris@39: eJackGeoLocHDMI, Chris@39: eJackGeoLocOutsideMobileLid, Chris@39: eJackGeoLocATAPI, Chris@39: eJackGeoLocReserved5, Chris@39: eJackGeoLocReserved6, Chris@39: } Chris@39: PaWasapiJackGeoLocation; Chris@39: Chris@39: Chris@39: /* Jack general location */ Chris@39: typedef enum PaWasapiJackGenLocation Chris@39: { Chris@39: eJackGenLocPrimaryBox = 0, Chris@39: eJackGenLocInternal, Chris@39: eJackGenLocSeparate, Chris@39: eJackGenLocOther Chris@39: } Chris@39: PaWasapiJackGenLocation; Chris@39: Chris@39: Chris@39: /* Jack's type of port */ Chris@39: typedef enum PaWasapiJackPortConnection Chris@39: { Chris@39: eJackPortConnJack = 0, Chris@39: eJackPortConnIntegratedDevice, Chris@39: eJackPortConnBothIntegratedAndJack, Chris@39: eJackPortConnUnknown Chris@39: } Chris@39: PaWasapiJackPortConnection; Chris@39: Chris@39: Chris@39: /* Thread priority */ Chris@39: typedef enum PaWasapiThreadPriority Chris@39: { Chris@39: eThreadPriorityNone = 0, Chris@39: eThreadPriorityAudio, //!< Default for Shared mode. Chris@39: eThreadPriorityCapture, Chris@39: eThreadPriorityDistribution, Chris@39: eThreadPriorityGames, Chris@39: eThreadPriorityPlayback, Chris@39: eThreadPriorityProAudio, //!< Default for Exclusive mode. Chris@39: eThreadPriorityWindowManager Chris@39: } Chris@39: PaWasapiThreadPriority; Chris@39: Chris@39: Chris@39: /* Stream descriptor. */ Chris@39: typedef struct PaWasapiJackDescription Chris@39: { Chris@39: unsigned long channelMapping; Chris@39: unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */ Chris@39: PaWasapiJackConnectionType connectionType; Chris@39: PaWasapiJackGeoLocation geoLocation; Chris@39: PaWasapiJackGenLocation genLocation; Chris@39: PaWasapiJackPortConnection portConnection; Chris@39: unsigned int isConnected; Chris@39: } Chris@39: PaWasapiJackDescription; Chris@39: Chris@39: Chris@39: /* Stream descriptor. */ Chris@39: typedef struct PaWasapiStreamInfo Chris@39: { Chris@39: unsigned long size; /**< sizeof(PaWasapiStreamInfo) */ Chris@39: PaHostApiTypeId hostApiType; /**< paWASAPI */ Chris@39: unsigned long version; /**< 1 */ Chris@39: Chris@39: unsigned long flags; /**< collection of PaWasapiFlags */ Chris@39: Chris@39: /* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains Chris@39: paWinWasapiUseChannelMask this allows you to specify which speakers Chris@39: to address in a multichannel stream. Constants for channelMask Chris@39: are specified in pa_win_waveformat.h. Will be used only if Chris@39: paWinWasapiUseChannelMask flag is specified. Chris@39: */ Chris@39: PaWinWaveFormatChannelMask channelMask; Chris@39: Chris@39: /* Delivers raw data to callback obtained from GetBuffer() methods skipping Chris@39: internal PortAudio processing inventory completely. userData parameter will Chris@39: be the same that was passed to Pa_OpenStream method. Will be used only if Chris@39: paWinWasapiRedirectHostProcessor flag is specified. Chris@39: */ Chris@39: PaWasapiHostProcessorCallback hostProcessorOutput; Chris@39: PaWasapiHostProcessorCallback hostProcessorInput; Chris@39: Chris@39: /* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag Chris@39: is specified. Chris@39: Chris@39: Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode) Chris@39: you shall specify same value for threadPriority or othervise one of the values will be used Chris@39: to setup thread priority. Chris@39: */ Chris@39: PaWasapiThreadPriority threadPriority; Chris@39: } Chris@39: PaWasapiStreamInfo; Chris@39: Chris@39: Chris@39: /** Returns default sound format for device. Format is represented by PaWinWaveFormat or Chris@39: WAVEFORMATEXTENSIBLE structure. Chris@39: Chris@39: @param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. Chris@39: @param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes. Chris@39: @param nDevice Device index. Chris@39: Chris@39: @return Non-negative value indicating the number of bytes copied into format decriptor Chris@39: or, a PaErrorCode (which are always negative) if PortAudio is not initialized Chris@39: or an error is encountered. Chris@39: */ Chris@39: int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice ); Chris@39: Chris@39: Chris@39: /** Returns device role (PaWasapiDeviceRole enum). Chris@39: Chris@39: @param nDevice device index. Chris@39: Chris@39: @return Non-negative value indicating device role or, a PaErrorCode (which are always negative) Chris@39: if PortAudio is not initialized or an error is encountered. Chris@39: */ Chris@39: int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ); Chris@39: Chris@39: Chris@39: /** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread Chris@39: which makes calls to Pa_WriteStream/Pa_ReadStream. Chris@39: Chris@39: @param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority Chris@39: method to revert thread priority to initial state. Chris@39: Chris@39: @param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying Chris@39: eThreadPriorityNone does nothing. Chris@39: Chris@39: @return Error code indicating success or failure. Chris@39: @see PaWasapi_RevertThreadPriority Chris@39: */ Chris@39: PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass ); Chris@39: Chris@39: Chris@39: /** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread Chris@39: which makes calls to Pa_WriteStream/Pa_ReadStream. Chris@39: Chris@39: @param hTask Task handle obtained by PaWasapi_BoostThreadPriority method. Chris@39: @return Error code indicating success or failure. Chris@39: @see PaWasapi_BoostThreadPriority Chris@39: */ Chris@39: PaError PaWasapi_ThreadPriorityRevert( void *hTask ); Chris@39: Chris@39: Chris@39: /** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which Chris@39: can be locked for operations. Use this method as helper to findout maximal values of Chris@39: inputFrames/outputFrames of PaWasapiHostProcessorCallback. Chris@39: Chris@39: @param pStream Pointer to PaStream to query. Chris@39: @param nInput Pointer to variable to receive number of input frames. Can be NULL. Chris@39: @param nOutput Pointer to variable to receive number of output frames. Can be NULL. Chris@39: @return Error code indicating success or failure. Chris@39: @see PaWasapiHostProcessorCallback Chris@39: */ Chris@39: PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ); Chris@39: Chris@39: Chris@39: /** Get number of jacks associated with a WASAPI device. Use this method to determine if Chris@39: there are any jacks associated with the provided WASAPI device. Not all audio devices Chris@39: will support this capability. This is valid for both input and output devices. Chris@39: @param nDevice device index. Chris@39: @param jcount Number of jacks is returned in this variable Chris@39: @return Error code indicating success or failure Chris@39: @see PaWasapi_GetJackDescription Chris@39: */ Chris@39: PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount); Chris@39: Chris@39: Chris@39: /** Get the jack description associated with a WASAPI device and jack number Chris@39: Before this function is called, use PaWasapi_GetJackCount to determine the Chris@39: number of jacks associated with device. If jcount is greater than zero, then Chris@39: each jack from 0 to jcount can be queried with this function to get the jack Chris@39: description. Chris@39: @param nDevice device index. Chris@39: @param jindex Which jack to return information Chris@39: @param KSJACK_DESCRIPTION This structure filled in on success. Chris@39: @return Error code indicating success or failure Chris@39: @see PaWasapi_GetJackCount Chris@39: */ Chris@39: PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription); Chris@39: Chris@39: Chris@39: /* Chris@39: IMPORTANT: Chris@39: Chris@39: WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive Chris@39: share modes. Chris@39: Chris@39: Exclusive Mode: Chris@39: Chris@39: Exclusive mode allows to deliver audio data directly to hardware bypassing Chris@39: software mixing. Chris@39: Exclusive mode is specified by 'paWinWasapiExclusive' flag. Chris@39: Chris@39: Callback Interface: Chris@39: Chris@39: Provides best audio quality with low latency. Callback interface is implemented in Chris@39: two versions: Chris@39: Chris@39: 1) Event-Driven: Chris@39: This is the most powerful WASAPI implementation which provides glitch-free Chris@39: audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is Chris@39: 3 ms for HD Audio class audio chips. For the Shared mode latency can not be Chris@39: lower than 20 ms. Chris@39: Chris@39: 2) Poll-Driven: Chris@39: Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven Chris@39: and provides latency at around 10-13ms. Polling must be used to overcome a system bug Chris@39: under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply Chris@39: times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug Chris@39: does not exist in Vista x86 or Windows 7. Chris@39: Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects Chris@39: WOW64 bug and sets 'paWinWasapiPolling' automatically. Chris@39: Chris@39: Thread priority: Chris@39: Chris@39: Normally thread priority is set automatically and does not require modification. Although Chris@39: if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority' Chris@39: flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority Chris@39: enum. Chris@39: Chris@39: Blocking Interface: Chris@39: Chris@39: Blocking interface is implemented but due to above described Poll-Driven method can not Chris@39: deliver lowest possible latency. Specifying too low latency in Shared mode will result in Chris@39: distorted audio although Exclusive mode adds stability. Chris@39: Chris@39: Pa_IsFormatSupported: Chris@39: Chris@39: To check format with correct Share Mode (Exclusive/Shared) you must supply Chris@39: PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of Chris@39: PaStreamParameters::hostApiSpecificStreamInfo structure. Chris@39: Chris@39: Pa_OpenStream: Chris@39: Chris@39: To set desired Share Mode (Exclusive/Shared) you must supply Chris@39: PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of Chris@39: PaStreamParameters::hostApiSpecificStreamInfo structure. Chris@39: */ Chris@39: Chris@39: #ifdef __cplusplus Chris@39: } Chris@39: #endif /* __cplusplus */ Chris@39: Chris@39: #endif /* PA_WIN_WASAPI_H */