From: dmitrykos Date: Fri, 23 Jul 2010 10:04:03 +0000 (+0000) Subject: wasapi: X-Git-Tag: pa_stable_v19_20110326_r1647~101 X-Git-Url: https://andrewgundersen.net/repos?a=commitdiff_plain;h=f2badb7725aa0d9505c83665187db41e03d0a45c;p=portaudio wasapi: - added functionality to enumerate jacks and their description - added example which demonstrates jacks enumeration technique Thanks Reid Bishop for providing the idea for this extended functionality and patch with implementation. --- diff --git a/build/msvc/portaudio.def b/build/msvc/portaudio.def index 90c01a3..d25414f 100644 --- a/build/msvc/portaudio.def +++ b/build/msvc/portaudio.def @@ -45,4 +45,6 @@ PaWasapi_GetDeviceDefaultFormat @56 PaWasapi_GetDeviceRole @57 PaWasapi_ThreadPriorityBoost @58 PaWasapi_ThreadPriorityRevert @59 -PaWasapi_GetFramesPerHostBuffer @60 \ No newline at end of file +PaWasapi_GetFramesPerHostBuffer @60 +PaWasapi_GetJackDescription @61 +PaWasapi_GetJackCount @62 \ No newline at end of file diff --git a/include/pa_win_wasapi.h b/include/pa_win_wasapi.h index a0bcf7a..e949dfe 100644 --- a/include/pa_win_wasapi.h +++ b/include/pa_win_wasapi.h @@ -109,6 +109,70 @@ typedef enum PaWasapiDeviceRole 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 { @@ -124,6 +188,20 @@ typedef enum PaWasapiThreadPriority 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 descriptor. */ typedef struct PaWasapiStreamInfo { @@ -223,6 +301,31 @@ PaError PaWasapi_ThreadPriorityRevert( void *hTask ); 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: diff --git a/src/hostapi/wasapi/pa_win_wasapi.c b/src/hostapi/wasapi/pa_win_wasapi.c index ff4a3d3..e354928 100644 --- a/src/hostapi/wasapi/pa_win_wasapi.c +++ b/src/hostapi/wasapi/pa_win_wasapi.c @@ -53,9 +53,10 @@ #define COBJMACROS #include #include - #define INITGUID //<< avoid additional linkage of static libs, uneeded code will be optimized out + #define INITGUID // Avoid additional linkage of static libs, excessive code will be optimized out by the compiler #include #include + #include // Used to get IKsJackDescription interface #undef INITGUID #endif #ifndef __MWERKS__ @@ -275,6 +276,12 @@ PA_DEFINE_CLSID(IMMDeviceEnumerator,bcde0395, e52f, 467c, 8e, 3d, c4, 57, 92, 91 PA_DEFINE_IID(IAudioRenderClient, f294acfc, 3146, 4483, a7, bf, ad, dc, a7, c2, 60, e2); // "C8ADBD64-E71E-48a0-A4DE-185C395CD317" PA_DEFINE_IID(IAudioCaptureClient, c8adbd64, e71e, 48a0, a4, de, 18, 5c, 39, 5c, d3, 17); +// *2A07407E-6497-4A18-9787-32F79BD0D98F* Or this?? +PA_DEFINE_IID(IDeviceTopology, 2A07407E, 6497, 4A18, 97, 87, 32, f7, 9b, d0, d9, 8f); +// *AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9* +PA_DEFINE_IID(IPart, AE2DE0E4, 5BCA, 4F2D, aa, 46, 5d, 13, f8, fd, b3, a9); +// *4509F757-2D46-4637-8E62-CE7DB944F57B* +PA_DEFINE_IID(IKsJackDescription, 4509F757, 2D46, 4637, 8e, 62, ce, 7d, b9, 44, f5, 7b); // Media formats: __DEFINE_GUID(pa_KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); __DEFINE_GUID(pa_KSDATAFORMAT_SUBTYPE_ADPCM, 0x00000002, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 ); @@ -1422,7 +1429,7 @@ int PaWasapi_GetDeviceRole( PaDeviceIndex nDevice ) // Get API PaWasapiHostApiRepresentation *paWasapi = _GetHostApi(&ret); if (paWasapi == NULL) - return ret; + return paNotInitialized; // Get device index ret = PaUtil_DeviceIndexToHostApiDeviceIndex(&index, nDevice, &paWasapi->inheritedHostApiRep); @@ -3460,6 +3467,235 @@ PaError PaWasapi_ThreadPriorityRevert(void *hTask) return paNoError; } +// ------------------------------------------------------------------------------------------ +// Described at: +// http://msdn.microsoft.com/en-us/library/dd371387(v=VS.85).aspx + +PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount) +{ + PaError ret; + HRESULT hr = S_OK; + PaDeviceIndex index; + IDeviceTopology *pDeviceTopology = NULL; + IConnector *pConnFrom = NULL; + IConnector *pConnTo = NULL; + IPart *pPart = NULL; + IKsJackDescription *pJackDesc = NULL; + UINT jackCount = 0; + + PaWasapiHostApiRepresentation *paWasapi = _GetHostApi(&ret); + if (paWasapi == NULL) + return paNotInitialized; + + // Get device index. + ret = PaUtil_DeviceIndexToHostApiDeviceIndex(&index, nDevice, &paWasapi->inheritedHostApiRep); + if (ret != paNoError) + return ret; + + // Validate index. + if ((UINT32)index >= paWasapi->deviceCount) + return paInvalidDevice; + + // Get the endpoint device's IDeviceTopology interface. + hr = IMMDevice_Activate(paWasapi->devInfo[index].device, &pa_IID_IDeviceTopology, + CLSCTX_INPROC_SERVER, NULL, (void**)&pDeviceTopology); + IF_FAILED_JUMP(hr, error); + + // The device topology for an endpoint device always contains just one connector (connector number 0). + hr = IDeviceTopology_GetConnector(pDeviceTopology, 0, &pConnFrom); + IF_FAILED_JUMP(hr, error); + + // Step across the connection to the jack on the adapter. + hr = IConnector_GetConnectedTo(pConnFrom, &pConnTo); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) + { + // The adapter device is not currently active. + hr = E_NOINTERFACE; + } + IF_FAILED_JUMP(hr, error); + + // Get the connector's IPart interface. + hr = IConnector_QueryInterface(pConnTo, &pa_IID_IPart, (void**)&pPart); + IF_FAILED_JUMP(hr, error); + + // Activate the connector's IKsJackDescription interface. + hr = IPart_Activate(pPart, CLSCTX_INPROC_SERVER, &pa_IID_IKsJackDescription, (void**)&pJackDesc); + IF_FAILED_JUMP(hr, error); + + // Return jack count for this device. + hr = IKsJackDescription_GetJackCount(pJackDesc, &jackCount); + IF_FAILED_JUMP(hr, error); + + // Set. + (*jcount) = jackCount; + + // Ok. + ret = paNoError; + +error: + + SAFE_RELEASE(pDeviceTopology); + SAFE_RELEASE(pConnFrom); + SAFE_RELEASE(pConnTo); + SAFE_RELEASE(pPart); + SAFE_RELEASE(pJackDesc); + + LogHostError(hr); + return paNoError; +} + +// ------------------------------------------------------------------------------------------ +static PaWasapiJackConnectionType ConvertJackConnectionTypeWASAPIToPA(int connType) +{ + switch (connType) + { + case eConnTypeUnknown: return eJackConnTypeUnknown; + case eConnType3Point5mm: return eJackConnType3Point5mm; + case eConnTypeQuarter: return eJackConnTypeQuarter; + case eConnTypeAtapiInternal: return eJackConnTypeAtapiInternal; + case eConnTypeRCA: return eJackConnTypeRCA; + case eConnTypeOptical: return eJackConnTypeOptical; + case eConnTypeOtherDigital: return eJackConnTypeOtherDigital; + case eConnTypeOtherAnalog: return eJackConnTypeOtherAnalog; + case eConnTypeMultichannelAnalogDIN: return eJackConnTypeMultichannelAnalogDIN; + case eConnTypeXlrProfessional: return eJackConnTypeXlrProfessional; + case eConnTypeRJ11Modem: return eJackConnTypeRJ11Modem; + case eConnTypeCombination: return eJackConnTypeCombination; + } + return eJackConnTypeUnknown; +} + +// ------------------------------------------------------------------------------------------ +static PaWasapiJackGeoLocation ConvertJackGeoLocationWASAPIToPA(int geoLoc) +{ + switch (geoLoc) + { + case eGeoLocRear: return eJackGeoLocRear; + case eGeoLocFront: return eJackGeoLocFront; + case eGeoLocLeft: return eJackGeoLocLeft; + case eGeoLocRight: return eJackGeoLocRight; + case eGeoLocTop: return eJackGeoLocTop; + case eGeoLocBottom: return eJackGeoLocBottom; + case eGeoLocRearPanel: return eJackGeoLocRearPanel; + case eGeoLocRiser: return eJackGeoLocRiser; + case eGeoLocInsideMobileLid: return eJackGeoLocInsideMobileLid; + case eGeoLocDrivebay: return eJackGeoLocDrivebay; + case eGeoLocHDMI: return eJackGeoLocHDMI; + case eGeoLocOutsideMobileLid: return eJackGeoLocOutsideMobileLid; + case eGeoLocATAPI: return eJackGeoLocATAPI; + } + return eJackGeoLocUnk; +} + +// ------------------------------------------------------------------------------------------ +static PaWasapiJackGenLocation ConvertJackGenLocationWASAPIToPA(int genLoc) +{ + switch (genLoc) + { + case eGenLocPrimaryBox: return eJackGenLocPrimaryBox; + case eGenLocInternal: return eJackGenLocInternal; + case eGenLocSeparate: return eJackGenLocSeparate; + case eGenLocOther: return eJackGenLocOther; + } + return eJackGenLocPrimaryBox; +} + +// ------------------------------------------------------------------------------------------ +static PaWasapiJackPortConnection ConvertJackPortConnectionWASAPIToPA(int portConn) +{ + switch (portConn) + { + case ePortConnJack: return eJackPortConnJack; + case ePortConnIntegratedDevice: return eJackPortConnIntegratedDevice; + case ePortConnBothIntegratedAndJack:return eJackPortConnBothIntegratedAndJack; + case ePortConnUnknown: return eJackPortConnUnknown; + } + return eJackPortConnJack; +} + +// ------------------------------------------------------------------------------------------ +// Described at: +// http://msdn.microsoft.com/en-us/library/dd371387(v=VS.85).aspx + +PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription) +{ + PaError ret; + HRESULT hr = S_OK; + PaDeviceIndex index; + IDeviceTopology *pDeviceTopology = NULL; + IConnector *pConnFrom = NULL; + IConnector *pConnTo = NULL; + IPart *pPart = NULL; + IKsJackDescription *pJackDesc = NULL; + KSJACK_DESCRIPTION jack = { 0 }; + + PaWasapiHostApiRepresentation *paWasapi = _GetHostApi(&ret); + if (paWasapi == NULL) + return paNotInitialized; + + // Get device index. + ret = PaUtil_DeviceIndexToHostApiDeviceIndex(&index, nDevice, &paWasapi->inheritedHostApiRep); + if (ret != paNoError) + return ret; + + // Validate index. + if ((UINT32)index >= paWasapi->deviceCount) + return paInvalidDevice; + + // Get the endpoint device's IDeviceTopology interface. + hr = IMMDevice_Activate(paWasapi->devInfo[index].device, &pa_IID_IDeviceTopology, + CLSCTX_INPROC_SERVER, NULL, (void**)&pDeviceTopology); + IF_FAILED_JUMP(hr, error); + + // The device topology for an endpoint device always contains just one connector (connector number 0). + hr = IDeviceTopology_GetConnector(pDeviceTopology, 0, &pConnFrom); + IF_FAILED_JUMP(hr, error); + + // Step across the connection to the jack on the adapter. + hr = IConnector_GetConnectedTo(pConnFrom, &pConnTo); + if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) + { + // The adapter device is not currently active. + hr = E_NOINTERFACE; + } + IF_FAILED_JUMP(hr, error); + + // Get the connector's IPart interface. + hr = IConnector_QueryInterface(pConnTo, &pa_IID_IPart, (void**)&pPart); + IF_FAILED_JUMP(hr, error); + + // Activate the connector's IKsJackDescription interface. + hr = IPart_Activate(pPart, CLSCTX_INPROC_SERVER, &pa_IID_IKsJackDescription, (void**)&pJackDesc); + IF_FAILED_JUMP(hr, error); + + // Test to return jack description struct for index 0. + hr = IKsJackDescription_GetJackDescription(pJackDesc, jindex, &jack); + IF_FAILED_JUMP(hr, error); + + // Convert WASAPI values to PA format. + pJackDescription->channelMapping = jack.ChannelMapping; + pJackDescription->color = jack.Color; + pJackDescription->connectionType = ConvertJackConnectionTypeWASAPIToPA(jack.ConnectionType); + pJackDescription->genLocation = ConvertJackGenLocationWASAPIToPA(jack.GenLocation); + pJackDescription->geoLocation = ConvertJackGeoLocationWASAPIToPA(jack.GeoLocation); + pJackDescription->isConnected = jack.IsConnected; + pJackDescription->portConnection = ConvertJackPortConnectionWASAPIToPA(jack.PortConnection); + + // Ok. + ret = paNoError; + +error: + + SAFE_RELEASE(pDeviceTopology); + SAFE_RELEASE(pConnFrom); + SAFE_RELEASE(pConnTo); + SAFE_RELEASE(pPart); + SAFE_RELEASE(pJackDesc); + + LogHostError(hr); + return ret; +} + // ------------------------------------------------------------------------------------------ static HRESULT ProcessOutputBuffer(PaWasapiStream *stream, PaWasapiHostProcessor *processor, UINT32 frames) { diff --git a/test/patest_jack_wasapi.c b/test/patest_jack_wasapi.c new file mode 100644 index 0000000..fed1b05 --- /dev/null +++ b/test/patest_jack_wasapi.c @@ -0,0 +1,343 @@ +/** @file pa_test_jack_wasapi.c + @ingroup test_src + @brief Print out jack information for WASAPI endpoints + @author Reid Bishop +*/ +/* + * $Id: pa_test_jack_wasapi.c 1368 2008-03-01 00:38:27Z rbishop $ + * + * This program uses the PortAudio Portable Audio Library. + * For more information see: http://www.portaudio.com/ + * Copyright (c) 1999-2010 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. + */ +#include +#include "portaudio.h" +#include "pa_win_wasapi.h" + + +/* +* Helper function to determine if a given enum is present in mask variable +* +*/ +static int IsInMask(int val, int val2) +{ + return ((val & val2) == val2); +} + +/* +* This routine enumerates through the ChannelMapping for the IJackDescription +*/ + +static void EnumIJackChannels(int channelMapping) +{ + printf("Channel Mapping: "); + if(channelMapping == PAWIN_SPEAKER_DIRECTOUT) + { + printf("DIRECTOUT\n"); + return; + } + if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_LEFT)) + printf("FRONT_LEFT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_RIGHT)) + printf("FRONT_RIGHT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_CENTER)) + printf("FRONT_CENTER, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_LOW_FREQUENCY)) + printf("LOW_FREQUENCY, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_BACK_LEFT)) + printf("BACK_LEFT, "); + if(IsInMask(channelMapping,PAWIN_SPEAKER_BACK_RIGHT)) + printf("BACK_RIGHT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_LEFT_OF_CENTER)) + printf("FRONT_LEFT_OF_CENTER, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_FRONT_RIGHT_OF_CENTER)) + printf("FRONT_RIGHT_OF_CENTER, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_BACK_CENTER)) + printf("BACK_CENTER, "); + if(IsInMask(channelMapping,PAWIN_SPEAKER_SIDE_LEFT)) + printf("SIDE_LEFT, "); + if(IsInMask(channelMapping,PAWIN_SPEAKER_SIDE_RIGHT)) + printf("SIDE_RIGHT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_CENTER)) + printf("TOP_CENTER, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_FRONT_LEFT)) + printf("TOP_FRONT_LEFT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_FRONT_CENTER)) + printf("TOP_FRONT_CENTER, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_FRONT_RIGHT)) + printf("TOP_FRONT_RIGHT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_BACK_LEFT)) + printf("TOP_BACK_LEFT, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_BACK_CENTER)) + printf("TOP_BACK_CENTER, "); + if(IsInMask(channelMapping, PAWIN_SPEAKER_TOP_BACK_RIGHT)) + printf("TOP_BACK_RIGHT, "); + + printf("\n"); +} + +/* +* This routine enumerates through the Jack Connection Types enums for IJackDescription +*/ +static void EnumIJackConnectionType(int cType) +{ + printf("Connection Type: "); + switch(cType) + { + case eJackConnTypeUnknown: + printf("eJackConnTypeUnknown"); + break; + case eJackConnType3Point5mm: + printf("eJackConnType3Point5mm"); + break; + case eJackConnTypeQuarter: + printf("eJackConnTypeQuarter"); + break; + case eJackConnTypeAtapiInternal: + printf("eJackConnTypeAtapiInternal"); + break; + case eJackConnTypeRCA: + printf("eJackConnTypeRCA"); + break; + case eJackConnTypeOptical: + printf("eJackConnTypeOptical"); + break; + case eJackConnTypeOtherDigital: + printf("eJackConnTypeOtherDigital"); + break; + case eJackConnTypeOtherAnalog: + printf("eJackConnTypeOtherAnalog"); + break; + case eJackConnTypeMultichannelAnalogDIN: + printf("eJackConnTypeMultichannelAnalogDIN"); + break; + case eJackConnTypeXlrProfessional: + printf("eJackConnTypeXlrProfessional"); + break; + case eJackConnTypeRJ11Modem: + printf("eJackConnTypeRJ11Modem"); + break; + case eJackConnTypeCombination: + printf("eJackConnTypeCombination"); + break; + } + printf("\n"); +} + +/* +* This routine enumerates through the GeoLocation enums for the IJackDescription +*/ +static void EnumIJackGeoLocation(int iVal) +{ + printf("Geometric Location: "); + switch(iVal) + { + case eJackGeoLocRear: + printf("eJackGeoLocRear"); + break; + case eJackGeoLocFront: + printf("eJackGeoLocFront"); + break; + case eJackGeoLocLeft: + printf("eJackGeoLocLeft"); + break; + case eJackGeoLocRight: + printf("eJackGeoLocRight"); + break; + case eJackGeoLocTop: + printf("eJackGeoLocTop"); + break; + case eJackGeoLocBottom: + printf("eJackGeoLocBottom"); + break; + case eJackGeoLocRearPanel: + printf("eJackGeoLocRearPanel"); + break; + case eJackGeoLocRiser: + printf("eJackGeoLocRiser"); + break; + case eJackGeoLocInsideMobileLid: + printf("eJackGeoLocInsideMobileLid"); + break; + case eJackGeoLocDrivebay: + printf("eJackGeoLocDrivebay"); + break; + case eJackGeoLocHDMI: + printf("eJackGeoLocHDMI"); + break; + case eJackGeoLocOutsideMobileLid: + printf("eJackGeoLocOutsideMobileLid"); + break; + case eJackGeoLocATAPI: + printf("eJackGeoLocATAPI"); + break; + } + printf("\n"); +} + +/* +* This routine enumerates through the GenLocation enums for the IJackDescription +*/ +static void EnumIJackGenLocation(int iVal) +{ + printf("General Location: "); + switch(iVal) + { + case eJackGenLocPrimaryBox: + printf("eJackGenLocPrimaryBox"); + break; + case eJackGenLocInternal: + printf("eJackGenLocInternal"); + break; + case eJackGenLocSeparate: + printf("eJackGenLocSeparate"); + break; + case eJackGenLocOther: + printf("eJackGenLocOther"); + break; + } + printf("\n"); +} + +/* +* This routine enumerates through the PortConnection enums for the IJackDescription +*/ +static void EnumIJackPortConnection(int iVal) +{ + printf("Port Type: "); + switch(iVal) + { + case eJackPortConnJack: + printf("eJackPortConnJack"); + break; + case eJackPortConnIntegratedDevice: + printf("eJackPortConnIntegratedDevice"); + break; + case eJackPortConnBothIntegratedAndJack: + printf("eJackPortConnBothIntegratedAndJack"); + break; + case eJackPortConnUnknown: + printf("eJackPortConnUnknown"); + break; + } + printf("\n"); +} + +/* +* This routine retrieves and parses the KSJACK_DESCRIPTION structure for +* the provided device ID. +*/ +static PaError GetJackInformation(int deviceId) +{ + PaError err; + int i; + int jackCount = 0; + PaWasapiJackDescription jackDesc; + + err = PaWasapi_GetJackCount(deviceId, &jackCount); + if( err != paNoError ) return err; + + fprintf( stderr,"Number of Jacks: %d \n", jackCount ); + + for( i = 0; ihostApi == Pa_HostApiTypeIdToHostApiIndex(paWASAPI) ) + { + if( device->maxOutputChannels == 0 ) + { + isInput = 1; + } + printf("------------------------------------------\n"); + printf("Device: %s",device->name); + if(isInput) + printf(" (Input) %d Channels\n",device->maxInputChannels); + else + printf(" (Output) %d Channels\n",device->maxOutputChannels); + // Try to see if this WASAPI device can provide Jack information + err = GetJackInformation(i); + if( err != paNoError ) goto error; + } + } + Pa_Terminate(); + printf("Test finished.\n"); + return err; + +error: + Pa_Terminate(); + fprintf( stderr, "An error occured while using the portaudio stream\n" ); + fprintf( stderr, "Error number: %d\n", err ); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return err; +}