diff --git a/lib-src/portaudio-v19/include/pa_win_ds.h b/lib-src/portaudio-v19/include/pa_win_ds.h index 5d38641..f8197e5 100644 --- a/lib-src/portaudio-v19/include/pa_win_ds.h +++ b/lib-src/portaudio-v19/include/pa_win_ds.h @@ -87,6 +87,22 @@ typedef struct PaWinDirectSoundStreamInfo{ }PaWinDirectSoundStreamInfo; +/** Retrieve the GUID of the input device. + + @param stream The stream to query. + + @return A pointer to the GUID, or NULL if none. +*/ +LPGUID PaWinDS_GetStreamInputGUID( PaStream* s ); + +/** Retrieve the GUID of the output device. + + @param stream The stream to query. + + @return A pointer to the GUID, or NULL if none. +*/ +LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s ); + #ifdef __cplusplus } diff --git a/lib-src/portaudio-v19/include/pa_win_wasapi.h b/lib-src/portaudio-v19/include/pa_win_wasapi.h index 40d3a09..1087157 100644 --- a/lib-src/portaudio-v19/include/pa_win_wasapi.h +++ b/lib-src/portaudio-v19/include/pa_win_wasapi.h @@ -1,433 +1,447 @@ -#ifndef PA_WIN_WASAPI_H -#define PA_WIN_WASAPI_H -/* - * $Id: $ - * PortAudio Portable Real-Time Audio Library - * DirectSound specific extensions - * - * Copyright (c) 1999-2007 Ross Bencina and Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ - -/** @file - @ingroup public_header - @brief WASAPI-specific PortAudio API extension header file. -*/ - -#include "portaudio.h" -#include "pa_win_waveformat.h" - -#ifdef __cplusplus -extern "C" -{ -#endif /* __cplusplus */ - - -/* Setup flags */ -typedef enum PaWasapiFlags -{ - /* puts WASAPI into exclusive mode */ - paWinWasapiExclusive = (1 << 0), - - /* allows to skip internal PA processing completely */ - paWinWasapiRedirectHostProcessor = (1 << 1), - - /* assigns custom channel mask */ - paWinWasapiUseChannelMask = (1 << 2), - - /* selects non-Event driven method of data read/write - Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling - method can only provide 15-20ms latency. */ - paWinWasapiPolling = (1 << 3), - - /* forces custom thread priority setting, must be used if PaWasapiStreamInfo::threadPriority - is set to a custom value */ - paWinWasapiThreadPriority = (1 << 4) -} -PaWasapiFlags; -#define paWinWasapiExclusive (paWinWasapiExclusive) -#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor) -#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask) -#define paWinWasapiPolling (paWinWasapiPolling) -#define paWinWasapiThreadPriority (paWinWasapiThreadPriority) - - -/* Host processor. Allows to skip internal PA processing completely. - You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member - in order to have host processor redirected to your callback. - Use with caution! inputFrames and outputFrames depend solely on final device setup. - To query maximal values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer. -*/ -typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames, - void *outputBuffer, long outputFrames, - void *userData); - -/* Device role. */ -typedef enum PaWasapiDeviceRole -{ - eRoleRemoteNetworkDevice = 0, - eRoleSpeakers, - eRoleLineLevel, - eRoleHeadphones, - eRoleMicrophone, - eRoleHeadset, - eRoleHandset, - eRoleUnknownDigitalPassthrough, - eRoleSPDIF, - eRoleHDMI, - eRoleUnknownFormFactor -} -PaWasapiDeviceRole; - - -/* Jack connection type. */ -typedef enum PaWasapiJackConnectionType -{ - eJackConnTypeUnknown, - eJackConnType3Point5mm, - eJackConnTypeQuarter, - eJackConnTypeAtapiInternal, - eJackConnTypeRCA, - eJackConnTypeOptical, - eJackConnTypeOtherDigital, - eJackConnTypeOtherAnalog, - eJackConnTypeMultichannelAnalogDIN, - eJackConnTypeXlrProfessional, - eJackConnTypeRJ11Modem, - eJackConnTypeCombination -} -PaWasapiJackConnectionType; - - -/* Jack geometric location. */ -typedef enum PaWasapiJackGeoLocation -{ - eJackGeoLocUnk = 0, - eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */ - eJackGeoLocFront, - eJackGeoLocLeft, - eJackGeoLocRight, - eJackGeoLocTop, - eJackGeoLocBottom, - eJackGeoLocRearPanel, - eJackGeoLocRiser, - eJackGeoLocInsideMobileLid, - eJackGeoLocDrivebay, - eJackGeoLocHDMI, - eJackGeoLocOutsideMobileLid, - eJackGeoLocATAPI, - eJackGeoLocReserved5, - eJackGeoLocReserved6, -} -PaWasapiJackGeoLocation; - - -/* Jack general location. */ -typedef enum PaWasapiJackGenLocation -{ - eJackGenLocPrimaryBox = 0, - eJackGenLocInternal, - eJackGenLocSeparate, - eJackGenLocOther -} -PaWasapiJackGenLocation; - - -/* Jack's type of port. */ -typedef enum PaWasapiJackPortConnection -{ - eJackPortConnJack = 0, - eJackPortConnIntegratedDevice, - eJackPortConnBothIntegratedAndJack, - eJackPortConnUnknown -} -PaWasapiJackPortConnection; - - -/* Thread priority. */ -typedef enum PaWasapiThreadPriority -{ - eThreadPriorityNone = 0, - eThreadPriorityAudio, //!< Default for Shared mode. - eThreadPriorityCapture, - eThreadPriorityDistribution, - eThreadPriorityGames, - eThreadPriorityPlayback, - eThreadPriorityProAudio, //!< Default for Exclusive mode. - eThreadPriorityWindowManager -} -PaWasapiThreadPriority; - - -/* Stream descriptor. */ -typedef struct PaWasapiJackDescription -{ - unsigned long channelMapping; - unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */ - PaWasapiJackConnectionType connectionType; - PaWasapiJackGeoLocation geoLocation; - PaWasapiJackGenLocation genLocation; - PaWasapiJackPortConnection portConnection; - unsigned int isConnected; -} -PaWasapiJackDescription; - - -/* Stream category. - Note: - - values are equal to WASAPI AUDIO_STREAM_CATEGORY enum - - supported since Windows 8.0, noop on earler versions - - values 1,2 are deprecated on Windows 10 and not included into enumeration -*/ -typedef enum PaWasapiStreamCategory -{ - eAudioCategoryOther = 0, - eAudioCategoryCommunications = 3, - eAudioCategoryAlerts = 4, - eAudioCategorySoundEffects = 5, - eAudioCategoryGameEffects = 6, - eAudioCategoryGameMedia = 7, - eAudioCategoryGameChat = 8, - eAudioCategorySpeech = 9, - eAudioCategoryMovie = 10, - eAudioCategoryMedia = 11 -} -PaWasapiStreamCategory; - - -/* Stream option. - Note: - - values are equal to WASAPI AUDCLNT_STREAMOPTIONS enum - - supported since Windows 8.1, noop on earler versions -*/ -typedef enum PaWasapiStreamOption -{ - eStreamOptionNone = 0, //!< default - eStreamOptionRaw = 1, //!< bypass WASAPI Audio Engine DSP effects, supported since Windows 8.1 - eStreamOptionMatchFormat = 2 //!< force WASAPI Audio Engine into a stream format, supported since Windows 10 -} -PaWasapiStreamOption; - - -/* Stream descriptor. */ -typedef struct PaWasapiStreamInfo -{ - unsigned long size; /**< sizeof(PaWasapiStreamInfo) */ - PaHostApiTypeId hostApiType; /**< paWASAPI */ - unsigned long version; /**< 1 */ - - unsigned long flags; /**< collection of PaWasapiFlags */ - - /* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains - paWinWasapiUseChannelMask this allows you to specify which speakers - to address in a multichannel stream. Constants for channelMask - are specified in pa_win_waveformat.h. Will be used only if - paWinWasapiUseChannelMask flag is specified. - */ - PaWinWaveFormatChannelMask channelMask; - - /* Delivers raw data to callback obtained from GetBuffer() methods skipping - internal PortAudio processing inventory completely. userData parameter will - be the same that was passed to Pa_OpenStream method. Will be used only if - paWinWasapiRedirectHostProcessor flag is specified. - */ - PaWasapiHostProcessorCallback hostProcessorOutput; - PaWasapiHostProcessorCallback hostProcessorInput; - - /* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag - is specified. - - Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode) - you shall specify same value for threadPriority or othervise one of the values will be used - to setup thread priority. - */ - PaWasapiThreadPriority threadPriority; - - /* Stream category. */ - PaWasapiStreamCategory streamCategory; - - /* Stream option. */ - PaWasapiStreamOption streamOption; -} -PaWasapiStreamInfo; - - -/** Returns default sound format for device. Format is represented by PaWinWaveFormat or - WAVEFORMATEXTENSIBLE structure. - - @param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. - @param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes. - @param nDevice Device index. - - @return Non-negative value indicating the number of bytes copied into format decriptor - or, a PaErrorCode (which are always negative) if PortAudio is not initialized - or an error is encountered. -*/ -int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice ); - - -/** Returns device role (PaWasapiDeviceRole enum). - - @param nDevice device index. - - @return Non-negative value indicating device role or, a PaErrorCode (which are always negative) - if PortAudio is not initialized or an error is encountered. -*/ -int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ); - - -/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread - which makes calls to Pa_WriteStream/Pa_ReadStream. - - @param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority - method to revert thread priority to initial state. - - @param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying - eThreadPriorityNone does nothing. - - @return Error code indicating success or failure. - @see PaWasapi_RevertThreadPriority -*/ -PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass ); - - -/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread - which makes calls to Pa_WriteStream/Pa_ReadStream. - - @param hTask Task handle obtained by PaWasapi_BoostThreadPriority method. - @return Error code indicating success or failure. - @see PaWasapi_BoostThreadPriority -*/ -PaError PaWasapi_ThreadPriorityRevert( void *hTask ); - - -/** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which - can be locked for operations. Use this method as helper to findout maximal values of - inputFrames/outputFrames of PaWasapiHostProcessorCallback. - - @param pStream Pointer to PaStream to query. - @param nInput Pointer to variable to receive number of input frames. Can be NULL. - @param nOutput Pointer to variable to receive number of output frames. Can be NULL. - @return Error code indicating success or failure. - @see PaWasapiHostProcessorCallback -*/ -PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ); - - -/** Get number of jacks associated with a WASAPI device. Use this method to determine if - there are any jacks associated with the provided WASAPI device. Not all audio devices - will support this capability. This is valid for both input and output devices. - @param nDevice device index. - @param jcount Number of jacks is returned in this variable - @return Error code indicating success or failure - @see PaWasapi_GetJackDescription - */ -PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount); - - -/** Get the jack description associated with a WASAPI device and jack number - Before this function is called, use PaWasapi_GetJackCount to determine the - number of jacks associated with device. If jcount is greater than zero, then - each jack from 0 to jcount can be queried with this function to get the jack - description. - @param nDevice device index. - @param jindex Which jack to return information - @param KSJACK_DESCRIPTION This structure filled in on success. - @return Error code indicating success or failure - @see PaWasapi_GetJackCount - */ -PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription); - - -/* - IMPORTANT: - - WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive - share modes. - - Exclusive Mode: - - Exclusive mode allows to deliver audio data directly to hardware bypassing - software mixing. - Exclusive mode is specified by 'paWinWasapiExclusive' flag. - - Callback Interface: - - Provides best audio quality with low latency. Callback interface is implemented in - two versions: - - 1) Event-Driven: - This is the most powerful WASAPI implementation which provides glitch-free - audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is - 3 ms for HD Audio class audio chips. For the Shared mode latency can not be - lower than 20 ms. - - 2) Poll-Driven: - Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven - and provides latency at around 10-13ms. Polling must be used to overcome a system bug - under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply - times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug - does not exist in Vista x86 or Windows 7. - Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects - WOW64 bug and sets 'paWinWasapiPolling' automatically. - - Thread priority: - - Normally thread priority is set automatically and does not require modification. Although - if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority' - flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority - enum. - - Blocking Interface: - - Blocking interface is implemented but due to above described Poll-Driven method can not - deliver lowest possible latency. Specifying too low latency in Shared mode will result in - distorted audio although Exclusive mode adds stability. - - Pa_IsFormatSupported: - - To check format with correct Share Mode (Exclusive/Shared) you must supply - PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of - PaStreamParameters::hostApiSpecificStreamInfo structure. - - Pa_OpenStream: - - To set desired Share Mode (Exclusive/Shared) you must supply - PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of - PaStreamParameters::hostApiSpecificStreamInfo structure. -*/ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* PA_WIN_WASAPI_H */ +#ifndef PA_WIN_WASAPI_H +#define PA_WIN_WASAPI_H +/* + * $Id: $ + * PortAudio Portable Real-Time Audio Library + * DirectSound specific extensions + * + * Copyright (c) 1999-2007 Ross Bencina and Phil Burk + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ + +/** @file + @ingroup public_header + @brief WASAPI-specific PortAudio API extension header file. +*/ + +#include "portaudio.h" +#include "pa_win_waveformat.h" + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + + +/* Setup flags */ +typedef enum PaWasapiFlags +{ + /* puts WASAPI into exclusive mode */ + paWinWasapiExclusive = (1 << 0), + + /* allows to skip internal PA processing completely */ + paWinWasapiRedirectHostProcessor = (1 << 1), + + /* assigns custom channel mask */ + paWinWasapiUseChannelMask = (1 << 2), + + /* selects non-Event driven method of data read/write + Note: WASAPI Event driven core is capable of 2ms latency!!!, but Polling + method can only provide 15-20ms latency. */ + paWinWasapiPolling = (1 << 3), + + /* forces custom thread priority setting, must be used if PaWasapiStreamInfo::threadPriority + is set to a custom value */ + paWinWasapiThreadPriority = (1 << 4) +} +PaWasapiFlags; +#define paWinWasapiExclusive (paWinWasapiExclusive) +#define paWinWasapiRedirectHostProcessor (paWinWasapiRedirectHostProcessor) +#define paWinWasapiUseChannelMask (paWinWasapiUseChannelMask) +#define paWinWasapiPolling (paWinWasapiPolling) +#define paWinWasapiThreadPriority (paWinWasapiThreadPriority) + + +/* Host processor. Allows to skip internal PA processing completely. + You must set paWinWasapiRedirectHostProcessor flag to PaWasapiStreamInfo::flags member + in order to have host processor redirected to your callback. + Use with caution! inputFrames and outputFrames depend solely on final device setup. + To query maximal values of inputFrames/outputFrames use PaWasapi_GetFramesPerHostBuffer. +*/ +typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFrames, + void *outputBuffer, long outputFrames, + void *userData); + +/* Device role. */ +typedef enum PaWasapiDeviceRole +{ + eRoleRemoteNetworkDevice = 0, + eRoleSpeakers, + eRoleLineLevel, + eRoleHeadphones, + eRoleMicrophone, + eRoleHeadset, + eRoleHandset, + eRoleUnknownDigitalPassthrough, + eRoleSPDIF, + eRoleHDMI, + eRoleUnknownFormFactor +} +PaWasapiDeviceRole; + + +/* Jack connection type. */ +typedef enum PaWasapiJackConnectionType +{ + eJackConnTypeUnknown, + eJackConnType3Point5mm, + eJackConnTypeQuarter, + eJackConnTypeAtapiInternal, + eJackConnTypeRCA, + eJackConnTypeOptical, + eJackConnTypeOtherDigital, + eJackConnTypeOtherAnalog, + eJackConnTypeMultichannelAnalogDIN, + eJackConnTypeXlrProfessional, + eJackConnTypeRJ11Modem, + eJackConnTypeCombination +} +PaWasapiJackConnectionType; + + +/* Jack geometric location. */ +typedef enum PaWasapiJackGeoLocation +{ + eJackGeoLocUnk = 0, + eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */ + eJackGeoLocFront, + eJackGeoLocLeft, + eJackGeoLocRight, + eJackGeoLocTop, + eJackGeoLocBottom, + eJackGeoLocRearPanel, + eJackGeoLocRiser, + eJackGeoLocInsideMobileLid, + eJackGeoLocDrivebay, + eJackGeoLocHDMI, + eJackGeoLocOutsideMobileLid, + eJackGeoLocATAPI, + eJackGeoLocReserved5, + eJackGeoLocReserved6, +} +PaWasapiJackGeoLocation; + + +/* Jack general location. */ +typedef enum PaWasapiJackGenLocation +{ + eJackGenLocPrimaryBox = 0, + eJackGenLocInternal, + eJackGenLocSeparate, + eJackGenLocOther +} +PaWasapiJackGenLocation; + + +/* Jack's type of port. */ +typedef enum PaWasapiJackPortConnection +{ + eJackPortConnJack = 0, + eJackPortConnIntegratedDevice, + eJackPortConnBothIntegratedAndJack, + eJackPortConnUnknown +} +PaWasapiJackPortConnection; + + +/* Thread priority. */ +typedef enum PaWasapiThreadPriority +{ + eThreadPriorityNone = 0, + eThreadPriorityAudio, //!< Default for Shared mode. + eThreadPriorityCapture, + eThreadPriorityDistribution, + eThreadPriorityGames, + eThreadPriorityPlayback, + eThreadPriorityProAudio, //!< Default for Exclusive mode. + eThreadPriorityWindowManager +} +PaWasapiThreadPriority; + + +/* Stream descriptor. */ +typedef struct PaWasapiJackDescription +{ + unsigned long channelMapping; + unsigned long color; /* derived from macro: #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) */ + PaWasapiJackConnectionType connectionType; + PaWasapiJackGeoLocation geoLocation; + PaWasapiJackGenLocation genLocation; + PaWasapiJackPortConnection portConnection; + unsigned int isConnected; +} +PaWasapiJackDescription; + + +/* Stream category. + Note: + - values are equal to WASAPI AUDIO_STREAM_CATEGORY enum + - supported since Windows 8.0, noop on earler versions + - values 1,2 are deprecated on Windows 10 and not included into enumeration +*/ +typedef enum PaWasapiStreamCategory +{ + eAudioCategoryOther = 0, + eAudioCategoryCommunications = 3, + eAudioCategoryAlerts = 4, + eAudioCategorySoundEffects = 5, + eAudioCategoryGameEffects = 6, + eAudioCategoryGameMedia = 7, + eAudioCategoryGameChat = 8, + eAudioCategorySpeech = 9, + eAudioCategoryMovie = 10, + eAudioCategoryMedia = 11 +} +PaWasapiStreamCategory; + + +/* Stream option. + Note: + - values are equal to WASAPI AUDCLNT_STREAMOPTIONS enum + - supported since Windows 8.1, noop on earler versions +*/ +typedef enum PaWasapiStreamOption +{ + eStreamOptionNone = 0, //!< default + eStreamOptionRaw = 1, //!< bypass WASAPI Audio Engine DSP effects, supported since Windows 8.1 + eStreamOptionMatchFormat = 2 //!< force WASAPI Audio Engine into a stream format, supported since Windows 10 +} +PaWasapiStreamOption; + + +/* Stream descriptor. */ +typedef struct PaWasapiStreamInfo +{ + unsigned long size; /**< sizeof(PaWasapiStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paWASAPI */ + unsigned long version; /**< 1 */ + + unsigned long flags; /**< collection of PaWasapiFlags */ + + /* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains + paWinWasapiUseChannelMask this allows you to specify which speakers + to address in a multichannel stream. Constants for channelMask + are specified in pa_win_waveformat.h. Will be used only if + paWinWasapiUseChannelMask flag is specified. + */ + PaWinWaveFormatChannelMask channelMask; + + /* Delivers raw data to callback obtained from GetBuffer() methods skipping + internal PortAudio processing inventory completely. userData parameter will + be the same that was passed to Pa_OpenStream method. Will be used only if + paWinWasapiRedirectHostProcessor flag is specified. + */ + PaWasapiHostProcessorCallback hostProcessorOutput; + PaWasapiHostProcessorCallback hostProcessorInput; + + /* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag + is specified. + + Please note, if Input/Output streams are opened simultaniously (Full-Duplex mode) + you shall specify same value for threadPriority or othervise one of the values will be used + to setup thread priority. + */ + PaWasapiThreadPriority threadPriority; + + /* Stream category. */ + PaWasapiStreamCategory streamCategory; + + /* Stream option. */ + PaWasapiStreamOption streamOption; +} +PaWasapiStreamInfo; + +/** Returns Windows device ID for input stream + + @param pStream Pointer to PaStream to query. + + @return non-null value pointing to static device ID +*/ +const wchar_t *PaWasapi_GetInputDeviceID( PaStream* s ); + +/** Returns Windows device ID for output stream + + @param pStream Pointer to PaStream to query. + + @return non-null value pointing to static device ID +*/ +const wchar_t *PaWasapi_GetOutputDeviceID( PaStream* s ); + +/** Returns default sound format for device. Format is represented by PaWinWaveFormat or + WAVEFORMATEXTENSIBLE structure. + + @param pFormat Pointer to PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure. + @param nFormatSize Size of PaWinWaveFormat or WAVEFORMATEXTENSIBLE structure in bytes. + @param nDevice Device index. + + @return Non-negative value indicating the number of bytes copied into format decriptor + or, a PaErrorCode (which are always negative) if PortAudio is not initialized + or an error is encountered. +*/ +int PaWasapi_GetDeviceDefaultFormat( void *pFormat, unsigned int nFormatSize, PaDeviceIndex nDevice ); + +/** Returns device role (PaWasapiDeviceRole enum). + + @param nDevice device index. + + @return Non-negative value indicating device role or, a PaErrorCode (which are always negative) + if PortAudio is not initialized or an error is encountered. +*/ +int/*PaWasapiDeviceRole*/ PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ); + + +/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread + which makes calls to Pa_WriteStream/Pa_ReadStream. + + @param hTask Handle to pointer to priority task. Must be used with PaWasapi_RevertThreadPriority + method to revert thread priority to initial state. + + @param nPriorityClass Id of thread priority of PaWasapiThreadPriority type. Specifying + eThreadPriorityNone does nothing. + + @return Error code indicating success or failure. + @see PaWasapi_RevertThreadPriority +*/ +PaError PaWasapi_ThreadPriorityBoost( void **hTask, PaWasapiThreadPriority nPriorityClass ); + + +/** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread + which makes calls to Pa_WriteStream/Pa_ReadStream. + + @param hTask Task handle obtained by PaWasapi_BoostThreadPriority method. + @return Error code indicating success or failure. + @see PaWasapi_BoostThreadPriority +*/ +PaError PaWasapi_ThreadPriorityRevert( void *hTask ); + + +/** Get number of frames per host buffer. This is maximal value of frames of WASAPI buffer which + can be locked for operations. Use this method as helper to findout maximal values of + inputFrames/outputFrames of PaWasapiHostProcessorCallback. + + @param pStream Pointer to PaStream to query. + @param nInput Pointer to variable to receive number of input frames. Can be NULL. + @param nOutput Pointer to variable to receive number of output frames. Can be NULL. + @return Error code indicating success or failure. + @see PaWasapiHostProcessorCallback +*/ +PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ); + + +/** Get number of jacks associated with a WASAPI device. Use this method to determine if + there are any jacks associated with the provided WASAPI device. Not all audio devices + will support this capability. This is valid for both input and output devices. + @param nDevice device index. + @param jcount Number of jacks is returned in this variable + @return Error code indicating success or failure + @see PaWasapi_GetJackDescription + */ +PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount); + + +/** Get the jack description associated with a WASAPI device and jack number + Before this function is called, use PaWasapi_GetJackCount to determine the + number of jacks associated with device. If jcount is greater than zero, then + each jack from 0 to jcount can be queried with this function to get the jack + description. + @param nDevice device index. + @param jindex Which jack to return information + @param KSJACK_DESCRIPTION This structure filled in on success. + @return Error code indicating success or failure + @see PaWasapi_GetJackCount + */ +PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription); + + +/* + IMPORTANT: + + WASAPI is implemented for Callback and Blocking interfaces. It supports Shared and Exclusive + share modes. + + Exclusive Mode: + + Exclusive mode allows to deliver audio data directly to hardware bypassing + software mixing. + Exclusive mode is specified by 'paWinWasapiExclusive' flag. + + Callback Interface: + + Provides best audio quality with low latency. Callback interface is implemented in + two versions: + + 1) Event-Driven: + This is the most powerful WASAPI implementation which provides glitch-free + audio at around 3ms latency in Exclusive mode. Lowest possible latency for this mode is + 3 ms for HD Audio class audio chips. For the Shared mode latency can not be + lower than 20 ms. + + 2) Poll-Driven: + Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven + and provides latency at around 10-13ms. Polling must be used to overcome a system bug + under Windows Vista x64 when application is WOW64(32-bit) and Event-Driven method simply + times out (event handle is never signalled on buffer completion). Please note, such WOW64 bug + does not exist in Vista x86 or Windows 7. + Polling can be setup by speciying 'paWinWasapiPolling' flag. Our WASAPI implementation detects + WOW64 bug and sets 'paWinWasapiPolling' automatically. + + Thread priority: + + Normally thread priority is set automatically and does not require modification. Although + if user wants some tweaking thread priority can be modified by setting 'paWinWasapiThreadPriority' + flag and specifying 'PaWasapiStreamInfo::threadPriority' with value from PaWasapiThreadPriority + enum. + + Blocking Interface: + + Blocking interface is implemented but due to above described Poll-Driven method can not + deliver lowest possible latency. Specifying too low latency in Shared mode will result in + distorted audio although Exclusive mode adds stability. + + Pa_IsFormatSupported: + + To check format with correct Share Mode (Exclusive/Shared) you must supply + PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of + PaStreamParameters::hostApiSpecificStreamInfo structure. + + Pa_OpenStream: + + To set desired Share Mode (Exclusive/Shared) you must supply + PaWasapiStreamInfo with flags paWinWasapiExclusive set through member of + PaStreamParameters::hostApiSpecificStreamInfo structure. +*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* PA_WIN_WASAPI_H */ diff --git a/lib-src/portaudio-v19/include/portaudio.h b/lib-src/portaudio-v19/include/portaudio.h index b8fa10a..f986e99 100644 --- a/lib-src/portaudio-v19/include/portaudio.h +++ b/lib-src/portaudio-v19/include/portaudio.h @@ -1180,6 +1180,15 @@ signed long Pa_GetStreamReadAvailable( PaStream* stream ); signed long Pa_GetStreamWriteAvailable( PaStream* stream ); +/** Retrieve the host type handling an open stream. + + @return Returns a non-negative value representing the host API type + handling an open stream or, a PaErrorCode (which are always negative) + if PortAudio is not initialized or an error is encountered. +*/ +PaHostApiTypeId Pa_GetStreamHostApiType( PaStream* stream ); + + /* Miscellaneous utilities */ diff --git a/lib-src/portaudio-v19/src/common/pa_front.c b/lib-src/portaudio-v19/src/common/pa_front.c index fad9192..ae4ac52 100644 --- a/lib-src/portaudio-v19/src/common/pa_front.c +++ b/lib-src/portaudio-v19/src/common/pa_front.c @@ -1255,8 +1255,10 @@ PaError Pa_OpenStream( PaStream** stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); - if( result == paNoError ) + if( result == paNoError ) { AddOpenStream( *stream ); + PA_STREAM_REP(*stream)->hostApiType = hostApi->info.type; + } PA_LOGAPI(("Pa_OpenStream returned:\n" )); @@ -1768,6 +1770,32 @@ signed long Pa_GetStreamWriteAvailable( PaStream* stream ) return result; } +PaHostApiTypeId Pa_GetStreamHostApiType( PaStream* stream ) +{ + PaError error = PaUtil_ValidateStreamPointer( stream ); + PaHostApiTypeId result; + +#ifdef PA_LOG_API_CALLS + PaUtil_DebugPrint("Pa_GetStreamHostApiType called:\n" ); + PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); +#endif + + if( error == paNoError ) + { + result = PA_STREAM_REP(stream)->hostApiType; + } + else + { + result = (PaHostApiTypeId) error; + } + +#ifdef PA_LOG_API_CALLS + PaUtil_DebugPrint("Pa_GetStreamHostApiType returned:\n" ); + PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) ); +#endif + + return result; +} PaError Pa_GetSampleSize( PaSampleFormat format ) { diff --git a/lib-src/portaudio-v19/src/common/pa_stream.c b/lib-src/portaudio-v19/src/common/pa_stream.c index ea91821..a7a381e 100644 --- a/lib-src/portaudio-v19/src/common/pa_stream.c +++ b/lib-src/portaudio-v19/src/common/pa_stream.c @@ -93,6 +93,8 @@ void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRe streamRepresentation->streamInfo.inputLatency = 0.; streamRepresentation->streamInfo.outputLatency = 0.; streamRepresentation->streamInfo.sampleRate = 0.; + + streamRepresentation->hostApiType = 0; } diff --git a/lib-src/portaudio-v19/src/common/pa_stream.h b/lib-src/portaudio-v19/src/common/pa_stream.h index 8d707b7..2f4abbc 100644 --- a/lib-src/portaudio-v19/src/common/pa_stream.h +++ b/lib-src/portaudio-v19/src/common/pa_stream.h @@ -152,6 +152,7 @@ typedef struct PaUtilStreamRepresentation { PaStreamFinishedCallback *streamFinishedCallback; void *userData; PaStreamInfo streamInfo; + PaHostApiTypeId hostApiType; } PaUtilStreamRepresentation; diff --git a/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c b/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c index ad63837..0ed0780 100644 --- a/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c +++ b/lib-src/portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c @@ -621,6 +621,7 @@ typedef struct StreamDirection streamDir; snd_pcm_channel_area_t *channelAreas; /* Needed for channel adaption */ + int card; } PaAlsaStreamComponent; /* Implementation specific stream structure */ @@ -1874,6 +1875,7 @@ static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, Pa PaError result = paNoError; PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat = paNoError; assert( params->channelCount > 0 ); + snd_pcm_info_t* pcmInfo; /* Make sure things have an initial value */ memset( self, 0, sizeof (PaAlsaStreamComponent) ); @@ -1902,6 +1904,9 @@ static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, Pa PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) ); self->nfds = alsa_snd_pcm_poll_descriptors_count( self->pcm ); + snd_pcm_info_alloca( &pcmInfo ); + self->card = snd_pcm_info_get_card( pcmInfo ); + PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ) ); self->hostSampleFormat = hostSampleFormat; @@ -4588,9 +4593,7 @@ PaError PaAlsa_GetStreamInputCard( PaStream* s, int* card ) /* XXX: More descriptive error? */ PA_UNLESS( stream->capture.pcm, paDeviceUnavailable ); - alsa_snd_pcm_info_alloca( &pcmInfo ); - PA_ENSURE( alsa_snd_pcm_info( stream->capture.pcm, pcmInfo ) ); - *card = alsa_snd_pcm_info_get_card( pcmInfo ); + *card = stream->capture.card; error: return result; @@ -4607,9 +4610,7 @@ PaError PaAlsa_GetStreamOutputCard( PaStream* s, int* card ) /* XXX: More descriptive error? */ PA_UNLESS( stream->playback.pcm, paDeviceUnavailable ); - alsa_snd_pcm_info_alloca( &pcmInfo ); - PA_ENSURE( alsa_snd_pcm_info( stream->playback.pcm, pcmInfo ) ); - *card = alsa_snd_pcm_info_get_card( pcmInfo ); + *card = stream->capture.card; error: return result; diff --git a/lib-src/portaudio-v19/src/hostapi/dsound/pa_win_ds.c b/lib-src/portaudio-v19/src/hostapi/dsound/pa_win_ds.c index 9dc95ac..d5f4636 100644 --- a/lib-src/portaudio-v19/src/hostapi/dsound/pa_win_ds.c +++ b/lib-src/portaudio-v19/src/hostapi/dsound/pa_win_ds.c @@ -257,6 +257,7 @@ typedef struct PaWinDsStream #endif /* Output */ + LPGUID pOutputGuid; LPDIRECTSOUND pDirectSound; LPDIRECTSOUNDBUFFER pDirectSoundPrimaryBuffer; LPDIRECTSOUNDBUFFER pDirectSoundOutputBuffer; @@ -272,6 +273,7 @@ typedef struct PaWinDsStream INT finalZeroBytesWritten; /* used to determine when we've flushed the whole buffer */ /* Input */ + LPGUID pInputGuid; LPDIRECTSOUNDCAPTURE pDirectSoundCapture; LPDIRECTSOUNDCAPTUREBUFFER pDirectSoundInputBuffer; INT inputFrameSizeBytes; @@ -1882,8 +1884,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; - PaSampleFormat inputSampleFormat, outputSampleFormat; - PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; + PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; + PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0; int userRequestedHostInputBufferSizeFrames = 0; int userRequestedHostOutputBufferSizeFrames = 0; unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames; @@ -2174,6 +2176,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, goto error; } + /* Portmixer support - fill in the GUID of the output stream */ + stream->pOutputGuid = outputWinDsDeviceInfo->lpGUID; + if( stream->pOutputGuid == NULL ) + { + stream->pOutputGuid = (GUID *) &DSDEVID_DefaultPlayback; + } + /* Calculate value used in latency calculation to avoid real-time divides. */ stream->secondsPerHostByte = 1.0 / (stream->bufferProcessor.bytesPerHostOutputSample * @@ -2215,6 +2224,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, result = paBufferTooBig; goto error; } + + /* Portmixer support - store the GUID of the input stream */ + stream->pInputGuid = inputWinDsDeviceInfo->lpGUID; + if( stream->pInputGuid == NULL ) + { + stream->pInputGuid = (GUID *)&DSDEVID_DefaultCapture; + } } /* open/create the DirectSound buffers */ @@ -2258,6 +2274,12 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, if( outputParameters && !stream->pDirectSoundOutputBuffer ) { + stream->pOutputGuid = outputWinDsDeviceInfo->lpGUID; + if( stream->pOutputGuid == NULL ) + { + stream->pOutputGuid = (GUID *) &DSDEVID_DefaultPlayback; + } + hr = InitOutputBuffer( stream, (PaWinDsDeviceInfo*)hostApi->deviceInfos[outputParameters->device], hostOutputSampleFormat, @@ -3266,3 +3288,18 @@ static signed long GetStreamWriteAvailable( PaStream* s ) return 0; } +/***********************************************************************************/ +LPGUID PaWinDS_GetStreamInputGUID( PaStream* s ) +{ + PaWinDsStream *stream = (PaWinDsStream*)s; + + return stream->pInputGuid; +} + +/***********************************************************************************/ +LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s ) +{ + PaWinDsStream *stream = (PaWinDsStream*)s; + + return stream->pOutputGuid; +} diff --git a/lib-src/portaudio-v19/src/hostapi/oss/pa_unix_oss.c b/lib-src/portaudio-v19/src/hostapi/oss/pa_unix_oss.c index 96e8a4e..586eedd 100644 --- a/lib-src/portaudio-v19/src/hostapi/oss/pa_unix_oss.c +++ b/lib-src/portaudio-v19/src/hostapi/oss/pa_unix_oss.c @@ -2043,3 +2043,26 @@ error: #endif } +const char *PaOSS_GetStreamInputDevice( PaStream* s ) +{ + PaOssStream *stream = (PaOssStream*)s; + + if( stream->capture ) + { + return stream->capture->devName; + } + + return NULL; +} + +const char *PaOSS_GetStreamOutputDevice( PaStream* s ) +{ + PaOssStream *stream = (PaOssStream*)s; + + if( stream->playback ) + { + return stream->playback->devName; + } + + return NULL; +} diff --git a/lib-src/portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c b/lib-src/portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c index 6e62a4a..de05d72 100644 --- a/lib-src/portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c +++ b/lib-src/portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c @@ -1662,6 +1662,32 @@ int PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ) } // ------------------------------------------------------------------------------------------ +const wchar_t *PaWasapi_GetInputDeviceID( PaStream* s ) +{ + PaWasapiStream *stream = (PaWasapiStream *)s; + if (stream == NULL) + return NULL; + + if (stream->in.params.device_info) + return stream->in.params.device_info->szDeviceID; + + return NULL; +} + +// ------------------------------------------------------------------------------------------ +const wchar_t *PaWasapi_GetOutputDeviceID( PaStream* s ) +{ + PaWasapiStream *stream = (PaWasapiStream *)s; + if (stream == NULL) + return NULL; + + if (stream->out.params.device_info) + return stream->out.params.device_info->szDeviceID; + + return NULL; +} + +// ------------------------------------------------------------------------------------------ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ) { PaWasapiStream *stream = (PaWasapiStream *)pStream; diff --git a/lib-src/portmixer/portaudio.patch b/lib-src/portmixer/portaudio.patch index a776cc1..e69de29 100644 --- a/lib-src/portmixer/portaudio.patch +++ b/lib-src/portmixer/portaudio.patch @@ -1,398 +0,0 @@ -diff -wruN portaudio/include/pa_unix_oss.h portaudio-v19/include/pa_unix_oss.h ---- portaudio/include/pa_unix_oss.h 1969-12-31 18:00:00.000000000 -0600 -+++ portaudio-v19/include/pa_unix_oss.h 2012-12-14 22:34:14.290247100 -0600 -@@ -0,0 +1,52 @@ -+#ifndef PA_UNIX_OSS_H -+#define PA_UNIX_OSS_H -+ -+/* -+ * $Id: portaudio.patch,v 1.10 2009-06-30 04:52:59 llucius Exp $ -+ * PortAudio Portable Real-Time Audio Library -+ * OSS-specific extensions -+ * -+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files -+ * (the "Software"), to deal in the Software without restriction, -+ * including without limitation the rights to use, copy, modify, merge, -+ * publish, distribute, sublicense, and/or sell copies of the Software, -+ * and to permit persons to whom the Software is furnished to do so, -+ * subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * Any person wishing to distribute modifications to the Software is -+ * requested to send the modifications to the original developer so that -+ * they can be incorporated into the canonical version. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR -+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ * -+ */ -+ -+/** @file -+ * OSS-specific PortAudio API extension header file. -+ */ -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+const char *PaOSS_GetStreamInputDevice( PaStream *s ); -+ -+const char *PaOSS_GetStreamOutputDevice( PaStream *s ); -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif -diff -wruN portaudio/include/pa_win_ds.h portaudio-v19/include/pa_win_ds.h ---- portaudio/include/pa_win_ds.h 2011-11-24 12:11:33.000000000 -0600 -+++ portaudio-v19/include/pa_win_ds.h 2012-12-14 22:35:51.384817600 -0600 -@@ -87,6 +87,22 @@ - }PaWinDirectSoundStreamInfo; - - -+/** Retrieve the GUID of the input device. -+ -+ @param stream The stream to query. -+ -+ @return A pointer to the GUID, or NULL if none. -+*/ -+LPGUID PaWinDS_GetStreamInputGUID( PaStream* s ); -+ -+/** Retrieve the GUID of the output device. -+ -+ @param stream The stream to query. -+ -+ @return A pointer to the GUID, or NULL if none. -+*/ -+LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s ); -+ - - #ifdef __cplusplus - } -diff -wruN portaudio/include/portaudio.h portaudio-v19/include/portaudio.h ---- portaudio/include/portaudio.h 2012-08-31 19:10:13.000000000 -0500 -+++ portaudio-v19/include/portaudio.h 2012-12-14 22:34:14.368247200 -0600 -@@ -1146,6 +1146,15 @@ - signed long Pa_GetStreamWriteAvailable( PaStream* stream ); - - -+/** Retrieve the host type handling an open stream. -+ -+ @return Returns a non-negative value representing the host API type -+ handling an open stream or, a PaErrorCode (which are always negative) -+ if PortAudio is not initialized or an error is encountered. -+*/ -+PaHostApiTypeId Pa_GetStreamHostApiType( PaStream* stream ); -+ -+ - /* Miscellaneous utilities */ - - -diff -wruN portaudio/src/common/pa_front.c portaudio-v19/src/common/pa_front.c ---- portaudio/src/common/pa_front.c 2012-12-04 12:39:48.000000000 -0600 -+++ portaudio-v19/src/common/pa_front.c 2012-12-14 09:44:34.604344800 -0600 -@@ -1216,8 +1216,10 @@ - hostApiInputParametersPtr, hostApiOutputParametersPtr, - sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); - -- if( result == paNoError ) -+ if( result == paNoError ) { - AddOpenStream( *stream ); -+ PA_STREAM_REP(*stream)->hostApiType = hostApi->info.type; -+ } - - - PA_LOGAPI(("Pa_OpenStream returned:\n" )); -@@ -1729,6 +1731,32 @@ - return result; - } - -+PaHostApiTypeId Pa_GetStreamHostApiType( PaStream* stream ) -+{ -+ PaError error = PaUtil_ValidateStreamPointer( stream ); -+ PaHostApiTypeId result; -+ -+#ifdef PA_LOG_API_CALLS -+ PaUtil_DebugPrint("Pa_GetStreamHostApiType called:\n" ); -+ PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream ); -+#endif -+ -+ if( error == paNoError ) -+ { -+ result = PA_STREAM_REP(stream)->hostApiType; -+ } -+ else -+ { -+ result = (PaHostApiTypeId) error; -+ } -+ -+#ifdef PA_LOG_API_CALLS -+ PaUtil_DebugPrint("Pa_GetStreamHostApiType returned:\n" ); -+ PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) ); -+#endif -+ -+ return result; -+} - - PaError Pa_GetSampleSize( PaSampleFormat format ) - { -diff -wruN portaudio/src/common/pa_stream.c portaudio-v19/src/common/pa_stream.c ---- portaudio/src/common/pa_stream.c 2008-02-15 01:50:33.000000000 -0600 -+++ portaudio-v19/src/common/pa_stream.c 2012-12-14 09:44:34.607345000 -0600 -@@ -93,6 +93,8 @@ - streamRepresentation->streamInfo.inputLatency = 0.; - streamRepresentation->streamInfo.outputLatency = 0.; - streamRepresentation->streamInfo.sampleRate = 0.; -+ -+ streamRepresentation->hostApiType = 0; - } - - -diff -wruN portaudio/src/common/pa_stream.h portaudio-v19/src/common/pa_stream.h ---- portaudio/src/common/pa_stream.h 2008-02-15 01:50:33.000000000 -0600 -+++ portaudio-v19/src/common/pa_stream.h 2012-12-14 09:44:34.610345200 -0600 -@@ -152,6 +152,7 @@ - PaStreamFinishedCallback *streamFinishedCallback; - void *userData; - PaStreamInfo streamInfo; -+ PaHostApiTypeId hostApiType; - } PaUtilStreamRepresentation; - - -diff -wruN portaudio/src/hostapi/alsa/pa_linux_alsa.c portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c ---- portaudio/src/hostapi/alsa/pa_linux_alsa.c 2012-05-18 11:04:30.000000000 -0500 -+++ portaudio-v19/src/hostapi/alsa/pa_linux_alsa.c 2012-12-14 10:00:12.133968500 -0600 -@@ -622,6 +622,7 @@ - StreamDirection streamDir; - - snd_pcm_channel_area_t *channelAreas; /* Needed for channel adaption */ -+ int card; - } PaAlsaStreamComponent; - - /* Implementation specific stream structure */ -@@ -1840,6 +1841,7 @@ - PaError result = paNoError; - PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat = paNoError; - assert( params->channelCount > 0 ); -+ snd_pcm_info_t* pcmInfo; - - /* Make sure things have an initial value */ - memset( self, 0, sizeof (PaAlsaStreamComponent) ); -@@ -1867,6 +1869,9 @@ - PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) ); - self->nfds = alsa_snd_pcm_poll_descriptors_count( self->pcm ); - -+ snd_pcm_info_alloca( &pcmInfo ); -+ self->card = snd_pcm_info_get_card( pcmInfo ); -+ - PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ) ); - - self->hostSampleFormat = hostSampleFormat; -@@ -4559,9 +4564,7 @@ - /* XXX: More descriptive error? */ - PA_UNLESS( stream->capture.pcm, paDeviceUnavailable ); - -- alsa_snd_pcm_info_alloca( &pcmInfo ); -- PA_ENSURE( alsa_snd_pcm_info( stream->capture.pcm, pcmInfo ) ); -- *card = alsa_snd_pcm_info_get_card( pcmInfo ); -+ *card = stream->capture.card; - - error: - return result; -@@ -4578,9 +4581,7 @@ - /* XXX: More descriptive error? */ - PA_UNLESS( stream->playback.pcm, paDeviceUnavailable ); - -- alsa_snd_pcm_info_alloca( &pcmInfo ); -- PA_ENSURE( alsa_snd_pcm_info( stream->playback.pcm, pcmInfo ) ); -- *card = alsa_snd_pcm_info_get_card( pcmInfo ); -+ *card = stream->capture.card; - - error: - return result; -diff -wruN portaudio/src/hostapi/dsound/pa_win_ds.c portaudio-v19/src/hostapi/dsound/pa_win_ds.c ---- portaudio/src/hostapi/dsound/pa_win_ds.c 2012-11-09 20:55:20.000000000 -0600 -+++ portaudio-v19/src/hostapi/dsound/pa_win_ds.c 2012-12-14 10:14:29.062982000 -0600 -@@ -257,6 +257,7 @@ - #endif - - /* Output */ -+ LPGUID pOutputGuid; - LPDIRECTSOUND pDirectSound; - LPDIRECTSOUNDBUFFER pDirectSoundPrimaryBuffer; - LPDIRECTSOUNDBUFFER pDirectSoundOutputBuffer; -@@ -272,6 +273,7 @@ - INT finalZeroBytesWritten; /* used to determine when we've flushed the whole buffer */ - - /* Input */ -+ LPGUID pInputGuid; - LPDIRECTSOUNDCAPTURE pDirectSoundCapture; - LPDIRECTSOUNDCAPTUREBUFFER pDirectSoundInputBuffer; - INT inputFrameSizeBytes; -@@ -1854,8 +1856,8 @@ - PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; - PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; - int inputChannelCount, outputChannelCount; -- PaSampleFormat inputSampleFormat, outputSampleFormat; -- PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat; -+ PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0; -+ PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0; - int userRequestedHostInputBufferSizeFrames = 0; - int userRequestedHostOutputBufferSizeFrames = 0; - unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames; -@@ -2146,6 +2148,13 @@ - goto error; - } - -+ /* Portmixer support - fill in the GUID of the output stream */ -+ stream->pOutputGuid = outputWinDsDeviceInfo->lpGUID; -+ if( stream->pOutputGuid == NULL ) -+ { -+ stream->pOutputGuid = (GUID *) &DSDEVID_DefaultPlayback; -+ } -+ - /* Calculate value used in latency calculation to avoid real-time divides. */ - stream->secondsPerHostByte = 1.0 / - (stream->bufferProcessor.bytesPerHostOutputSample * -@@ -2187,6 +2196,13 @@ - result = paBufferTooBig; - goto error; - } -+ -+ /* Portmixer support - store the GUID of the input stream */ -+ stream->pInputGuid = inputWinDsDeviceInfo->lpGUID; -+ if( stream->pInputGuid == NULL ) -+ { -+ stream->pInputGuid = (GUID *)&DSDEVID_DefaultCapture; -+ } - } - - /* open/create the DirectSound buffers */ -@@ -2230,6 +2246,12 @@ - - if( outputParameters && !stream->pDirectSoundOutputBuffer ) - { -+ stream->pOutputGuid = outputWinDsDeviceInfo->lpGUID; -+ if( stream->pOutputGuid == NULL ) -+ { -+ stream->pOutputGuid = (GUID *) &DSDEVID_DefaultPlayback; -+ } -+ - hr = InitOutputBuffer( stream, - (PaWinDsDeviceInfo*)hostApi->deviceInfos[outputParameters->device], - hostOutputSampleFormat, -@@ -3238,3 +3260,18 @@ - return 0; - } - -+/***********************************************************************************/ -+LPGUID PaWinDS_GetStreamInputGUID( PaStream* s ) -+{ -+ PaWinDsStream *stream = (PaWinDsStream*)s; -+ -+ return stream->pInputGuid; -+} -+ -+/***********************************************************************************/ -+LPGUID PaWinDS_GetStreamOutputGUID( PaStream* s ) -+{ -+ PaWinDsStream *stream = (PaWinDsStream*)s; -+ -+ return stream->pOutputGuid; -+} -diff -wruN portaudio/src/hostapi/oss/pa_unix_oss.c portaudio-v19/src/hostapi/oss/pa_unix_oss.c ---- portaudio/src/hostapi/oss/pa_unix_oss.c 2011-05-02 12:07:11.000000000 -0500 -+++ portaudio-v19/src/hostapi/oss/pa_unix_oss.c 2012-12-14 09:44:34.625346000 -0600 -@@ -2028,3 +2028,26 @@ - #endif - } - -+const char *PaOSS_GetStreamInputDevice( PaStream* s ) -+{ -+ PaOssStream *stream = (PaOssStream*)s; -+ -+ if( stream->capture ) -+ { -+ return stream->capture->devName; -+ } -+ -+ return NULL; -+} -+ -+const char *PaOSS_GetStreamOutputDevice( PaStream* s ) -+{ -+ PaOssStream *stream = (PaOssStream*)s; -+ -+ if( stream->playback ) -+ { -+ return stream->playback->devName; -+ } -+ -+ return NULL; -+} -diff -wruN orig/portaudio-v19/include/pa_win_wasapi.h portaudio-v19/include/pa_win_wasapi.h ---- orig/portaudio-v19/include/pa_win_wasapi.h 2013-09-23 23:44:18.192843200 -0500 -+++ portaudio-v19/include/pa_win_wasapi.h 2013-09-23 23:47:03.705310000 -0500 -@@ -272,6 +272,15 @@ - */ - int PaWasapi_IsLoopback( PaDeviceIndex nDevice ); - -+/** Returns Windows device ID. -+ -+ @param nDevice device index. -+ -+ @return 0 = Not loopback, 1 = loopback, < 0 = PaErrorCode -+ if PortAudio is not initialized or an error is encountered. -+*/ -+const wchar_t *PaWasapi_GetInputDeviceID( PaStream* s ); -+const wchar_t *PaWasapi_GetOutputDeviceID( PaStream* s ); - - /** Boost thread priority of calling thread (MMCSS). Use it for Blocking Interface only for thread - which makes calls to Pa_WriteStream/Pa_ReadStream. -diff -wruN orig/portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c ---- orig/portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c 2013-09-23 23:44:15.266675900 -0500 -+++ portaudio-v19/src/hostapi/wasapi/pa_win_wasapi.c 2013-09-23 23:47:03.709310200 -0500 -@@ -1608,6 +1608,32 @@ - } - - // ------------------------------------------------------------------------------------------ -+const wchar_t *PaWasapi_GetInputDeviceID( PaStream* s ) -+{ -+ PaWasapiStream *stream = (PaWasapiStream *)s; -+ if (stream == NULL) -+ return NULL; -+ -+ if (stream->in.params.device_info) -+ return stream->in.params.device_info->szDeviceID; -+ -+ return NULL; -+} -+ -+// ------------------------------------------------------------------------------------------ -+const wchar_t *PaWasapi_GetOutputDeviceID( PaStream* s ) -+{ -+ PaWasapiStream *stream = (PaWasapiStream *)s; -+ if (stream == NULL) -+ return NULL; -+ -+ if (stream->out.params.device_info) -+ return stream->out.params.device_info->szDeviceID; -+ -+ return NULL; -+} -+ -+// ------------------------------------------------------------------------------------------ - PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ) - { - PaWasapiStream *stream = (PaWasapiStream *)pStream;