diff --git a/lib-src/portaudio-v19/include/pa_win_ds.h b/lib-src/portaudio-v19/include/pa_win_ds.h index 5d3864168..f8197e531 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 9b827d1ea..a4416b121 100644 --- a/lib-src/portaudio-v19/include/pa_win_wasapi.h +++ b/lib-src/portaudio-v19/include/pa_win_wasapi.h @@ -548,6 +548,22 @@ PaError PaWasapi_SetDefaultInterfaceId( unsigned short *pId, int bOutput ); */ PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCallback fnStateHandler, void *pUserData ); +/** 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 ); + /* IMPORTANT: diff --git a/lib-src/portaudio-v19/include/portaudio.h b/lib-src/portaudio-v19/include/portaudio.h index 738080d43..ae1cbe280 100644 --- a/lib-src/portaudio-v19/include/portaudio.h +++ b/lib-src/portaudio-v19/include/portaudio.h @@ -1197,6 +1197,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 9d30f4837..b4b318692 100644 --- a/lib-src/portaudio-v19/src/common/pa_front.c +++ b/lib-src/portaudio-v19/src/common/pa_front.c @@ -1257,8 +1257,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" )); @@ -1770,6 +1772,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 03a0ee6ee..c4376f93b 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 678e2ad5e..70572c752 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 584cde890..5d44ace39 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; @@ -4605,9 +4610,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; @@ -4624,9 +4627,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 204004d84..63e9984c4 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; @@ -1885,8 +1887,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; @@ -2177,6 +2179,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 * @@ -2218,6 +2227,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 */ @@ -2261,6 +2277,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, @@ -3269,3 +3291,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 51e963048..f257d8039 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 1d8f20070..93e1d612a 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 @@ -5283,6 +5283,32 @@ PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCa return paNoError; } +// ------------------------------------------------------------------------------------------ +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; +} + // ------------------------------------------------------------------------------------------ HRESULT _PollGetOutputFramesAvailable(PaWasapiStream *stream, UINT32 *available) { diff --git a/lib-src/portmixer/portaudio.patch b/lib-src/portmixer/portaudio.patch index f028fc250..1ff3c99e5 100644 --- a/lib-src/portmixer/portaudio.patch +++ b/lib-src/portmixer/portaudio.patch @@ -1,5 +1,5 @@ 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 +index 5d3864168..f8197e531 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{ @@ -26,732 +26,20 @@ index 5d38641..f8197e5 100644 #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 +index 9b827d1ea..a4416b121 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; -+ +@@ -548,6 +548,22 @@ PaError PaWasapi_SetDefaultInterfaceId( unsigned short *pId, int bOutput ); + */ + PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCallback fnStateHandler, void *pUserData ); + +/** 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 ); ++const wchar_t *PaWasapi_GetInputDeviceID( PaStream *s ); + +/** Returns Windows device ID for output stream + @@ -759,162 +47,16 @@ index 40d3a09..1087157 100644 + + @return non-null value pointing to static device ID +*/ -+const wchar_t *PaWasapi_GetOutputDeviceID( PaStream* s ); ++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 */ + + /* + IMPORTANT: diff --git a/lib-src/portaudio-v19/include/portaudio.h b/lib-src/portaudio-v19/include/portaudio.h -index b8fa10a..f986e99 100644 +index 738080d43..ae1cbe280 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 ); +@@ -1197,6 +1197,15 @@ signed long Pa_GetStreamReadAvailable( PaStream* stream ); signed long Pa_GetStreamWriteAvailable( PaStream* stream ); @@ -931,10 +73,10 @@ index b8fa10a..f986e99 100644 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 +index 9d30f4837..b4b318692 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, +@@ -1257,8 +1257,10 @@ PaError Pa_OpenStream( PaStream** stream, hostApiInputParametersPtr, hostApiOutputParametersPtr, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData ); @@ -946,7 +88,7 @@ index fad9192..ae4ac52 100644 PA_LOGAPI(("Pa_OpenStream returned:\n" )); -@@ -1768,6 +1770,32 @@ signed long Pa_GetStreamWriteAvailable( PaStream* stream ) +@@ -1770,6 +1772,32 @@ signed long Pa_GetStreamWriteAvailable( PaStream* stream ) return result; } @@ -980,7 +122,7 @@ index fad9192..ae4ac52 100644 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 +index 03a0ee6ee..c4376f93b 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 @@ -993,7 +135,7 @@ index ea91821..a7a381e 100644 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 +index 678e2ad5e..70572c752 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 { @@ -1005,7 +147,7 @@ index 8d707b7..2f4abbc 100644 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 +index 584cde890..5d44ace39 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 @@ -1034,7 +176,7 @@ index ad63837..0ed0780 100644 PA_ENSURE( hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat ) ); self->hostSampleFormat = hostSampleFormat; -@@ -4588,9 +4593,7 @@ PaError PaAlsa_GetStreamInputCard( PaStream* s, int* card ) +@@ -4605,9 +4610,7 @@ PaError PaAlsa_GetStreamInputCard( PaStream* s, int* card ) /* XXX: More descriptive error? */ PA_UNLESS( stream->capture.pcm, paDeviceUnavailable ); @@ -1045,7 +187,7 @@ index ad63837..0ed0780 100644 error: return result; -@@ -4607,9 +4610,7 @@ PaError PaAlsa_GetStreamOutputCard( PaStream* s, int* card ) +@@ -4624,9 +4627,7 @@ PaError PaAlsa_GetStreamOutputCard( PaStream* s, int* card ) /* XXX: More descriptive error? */ PA_UNLESS( stream->playback.pcm, paDeviceUnavailable ); @@ -1057,7 +199,7 @@ index ad63837..0ed0780 100644 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 +index 204004d84..63e9984c4 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 @@ -1076,7 +218,7 @@ index 9dc95ac..d5f4636 100644 LPDIRECTSOUNDCAPTURE pDirectSoundCapture; LPDIRECTSOUNDCAPTUREBUFFER pDirectSoundInputBuffer; INT inputFrameSizeBytes; -@@ -1882,8 +1884,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, +@@ -1885,8 +1887,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, PaWinDsDeviceInfo *inputWinDsDeviceInfo, *outputWinDsDeviceInfo; PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo; int inputChannelCount, outputChannelCount; @@ -1087,7 +229,7 @@ index 9dc95ac..d5f4636 100644 int userRequestedHostInputBufferSizeFrames = 0; int userRequestedHostOutputBufferSizeFrames = 0; unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames; -@@ -2174,6 +2176,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, +@@ -2177,6 +2179,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, goto error; } @@ -1101,7 +243,7 @@ index 9dc95ac..d5f4636 100644 /* 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, +@@ -2218,6 +2227,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, result = paBufferTooBig; goto error; } @@ -1115,7 +257,7 @@ index 9dc95ac..d5f4636 100644 } /* open/create the DirectSound buffers */ -@@ -2258,6 +2274,12 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, +@@ -2261,6 +2277,12 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi, if( outputParameters && !stream->pDirectSoundOutputBuffer ) { @@ -1128,7 +270,7 @@ index 9dc95ac..d5f4636 100644 hr = InitOutputBuffer( stream, (PaWinDsDeviceInfo*)hostApi->deviceInfos[outputParameters->device], hostOutputSampleFormat, -@@ -3266,3 +3288,18 @@ static signed long GetStreamWriteAvailable( PaStream* s ) +@@ -3269,3 +3291,18 @@ static signed long GetStreamWriteAvailable( PaStream* s ) return 0; } @@ -1148,7 +290,7 @@ index 9dc95ac..d5f4636 100644 + 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 +index 51e963048..f257d8039 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: @@ -1179,14 +321,15 @@ index 96e8a4e..586eedd 100644 + 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 +index 1d8f20070..93e1d612a 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 ) +@@ -5283,6 +5283,32 @@ PaError PaWasapi_SetStreamStateHandler( PaStream *pStream, PaWasapiStreamStateCa + return paNoError; } - // ------------------------------------------------------------------------------------------ -+const wchar_t *PaWasapi_GetInputDeviceID( PaStream* s ) ++// ------------------------------------------------------------------------------------------ ++const wchar_t *PaWasapi_GetInputDeviceID( PaStream *s ) +{ + PaWasapiStream *stream = (PaWasapiStream *)s; + if (stream == NULL) @@ -1199,7 +342,7 @@ index 6e62a4a..de05d72 100644 +} + +// ------------------------------------------------------------------------------------------ -+const wchar_t *PaWasapi_GetOutputDeviceID( PaStream* s ) ++const wchar_t *PaWasapi_GetOutputDeviceID( PaStream *s ) +{ + PaWasapiStream *stream = (PaWasapiStream *)s; + if (stream == NULL) @@ -1211,410 +354,6 @@ index 6e62a4a..de05d72 100644 + return NULL; +} + -+// ------------------------------------------------------------------------------------------ - PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput, unsigned int *nOutput ) + // ------------------------------------------------------------------------------------------ + HRESULT _PollGetOutputFramesAvailable(PaWasapiStream *stream, UINT32 *available) { - 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;