Normalize all the line endings
This commit is contained in:
parent
b99790cb7c
commit
ed463ba658
141 changed files with 45010 additions and 45010 deletions
|
|
@ -1,144 +1,144 @@
|
|||
/*
|
||||
* Microsoft COM initialization routines
|
||||
* Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
* Copyright (c) 1999-2011 Ross Bencina, 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 win_src
|
||||
|
||||
@brief Microsoft COM initialization routines.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_debugprint.h"
|
||||
|
||||
#include "pa_win_coinitialize.h"
|
||||
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "ole32.lib" )
|
||||
#endif
|
||||
|
||||
|
||||
/* use some special bit patterns here to try to guard against uninitialized memory errors */
|
||||
#define PAWINUTIL_COM_INITIALIZED (0xb38f)
|
||||
#define PAWINUTIL_COM_NOT_INITIALIZED (0xf1cd)
|
||||
|
||||
|
||||
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
|
||||
|
||||
/*
|
||||
If COM is already initialized CoInitialize will either return
|
||||
FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different
|
||||
threading mode. In either case we shouldn't consider it an error
|
||||
but we need to be careful to not call CoUninitialize() if
|
||||
RPC_E_CHANGED_MODE was returned.
|
||||
*/
|
||||
|
||||
hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */
|
||||
if( FAILED(hr) && hr != RPC_E_CHANGED_MODE )
|
||||
{
|
||||
PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr));
|
||||
|
||||
if( hr == E_OUTOFMEMORY )
|
||||
return paInsufficientMemory;
|
||||
|
||||
{
|
||||
char *lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
hr,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf );
|
||||
LocalFree( lpMsgBuf );
|
||||
}
|
||||
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
|
||||
if( hr != RPC_E_CHANGED_MODE )
|
||||
{
|
||||
comInitializationResult->state = PAWINUTIL_COM_INITIALIZED;
|
||||
|
||||
/*
|
||||
Memorize calling thread id and report warning on Uninitialize if
|
||||
calling thread is different as CoInitialize must match CoUninitialize
|
||||
in the same thread.
|
||||
*/
|
||||
comInitializationResult->initializingThreadId = GetCurrentThreadId();
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
|
||||
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
|
||||
{
|
||||
if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED
|
||||
&& comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){
|
||||
|
||||
PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n"));
|
||||
}
|
||||
|
||||
if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED )
|
||||
{
|
||||
DWORD currentThreadId = GetCurrentThreadId();
|
||||
if( comInitializationResult->initializingThreadId != currentThreadId )
|
||||
{
|
||||
PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%d] does not match initializing thread[%d]\n",
|
||||
currentThreadId, comInitializationResult->initializingThreadId));
|
||||
}
|
||||
else
|
||||
{
|
||||
CoUninitialize();
|
||||
|
||||
comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Microsoft COM initialization routines
|
||||
* Copyright (c) 1999-2011 Ross Bencina, Dmitry Kostjuchenko
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
* Copyright (c) 1999-2011 Ross Bencina, 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 win_src
|
||||
|
||||
@brief Microsoft COM initialization routines.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_debugprint.h"
|
||||
|
||||
#include "pa_win_coinitialize.h"
|
||||
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "ole32.lib" )
|
||||
#endif
|
||||
|
||||
|
||||
/* use some special bit patterns here to try to guard against uninitialized memory errors */
|
||||
#define PAWINUTIL_COM_INITIALIZED (0xb38f)
|
||||
#define PAWINUTIL_COM_NOT_INITIALIZED (0xf1cd)
|
||||
|
||||
|
||||
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
|
||||
|
||||
/*
|
||||
If COM is already initialized CoInitialize will either return
|
||||
FALSE, or RPC_E_CHANGED_MODE if it was initialised in a different
|
||||
threading mode. In either case we shouldn't consider it an error
|
||||
but we need to be careful to not call CoUninitialize() if
|
||||
RPC_E_CHANGED_MODE was returned.
|
||||
*/
|
||||
|
||||
hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */
|
||||
if( FAILED(hr) && hr != RPC_E_CHANGED_MODE )
|
||||
{
|
||||
PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr));
|
||||
|
||||
if( hr == E_OUTOFMEMORY )
|
||||
return paInsufficientMemory;
|
||||
|
||||
{
|
||||
char *lpMsgBuf;
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
NULL,
|
||||
hr,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0,
|
||||
NULL
|
||||
);
|
||||
PaUtil_SetLastHostErrorInfo( hostApiType, hr, lpMsgBuf );
|
||||
LocalFree( lpMsgBuf );
|
||||
}
|
||||
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
|
||||
if( hr != RPC_E_CHANGED_MODE )
|
||||
{
|
||||
comInitializationResult->state = PAWINUTIL_COM_INITIALIZED;
|
||||
|
||||
/*
|
||||
Memorize calling thread id and report warning on Uninitialize if
|
||||
calling thread is different as CoInitialize must match CoUninitialize
|
||||
in the same thread.
|
||||
*/
|
||||
comInitializationResult->initializingThreadId = GetCurrentThreadId();
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
|
||||
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult )
|
||||
{
|
||||
if( comInitializationResult->state != PAWINUTIL_COM_NOT_INITIALIZED
|
||||
&& comInitializationResult->state != PAWINUTIL_COM_INITIALIZED ){
|
||||
|
||||
PA_DEBUG(("ERROR: PaWinUtil_CoUninitialize called without calling PaWinUtil_CoInitialize\n"));
|
||||
}
|
||||
|
||||
if( comInitializationResult->state == PAWINUTIL_COM_INITIALIZED )
|
||||
{
|
||||
DWORD currentThreadId = GetCurrentThreadId();
|
||||
if( comInitializationResult->initializingThreadId != currentThreadId )
|
||||
{
|
||||
PA_DEBUG(("ERROR: failed PaWinUtil_CoUninitialize calling thread[%d] does not match initializing thread[%d]\n",
|
||||
currentThreadId, comInitializationResult->initializingThreadId));
|
||||
}
|
||||
else
|
||||
{
|
||||
CoUninitialize();
|
||||
|
||||
comInitializationResult->state = PAWINUTIL_COM_NOT_INITIALIZED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +1,94 @@
|
|||
/*
|
||||
* Microsoft COM initialization routines
|
||||
* Copyright (c) 1999-2011 Ross Bencina, 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 win_src
|
||||
|
||||
@brief Microsoft COM initialization routines.
|
||||
*/
|
||||
|
||||
#ifndef PA_WIN_COINITIALIZE_H
|
||||
#define PA_WIN_COINITIALIZE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/**
|
||||
@brief Data type used to hold the result of an attempt to initialize COM
|
||||
using PaWinUtil_CoInitialize. Must be retained between a call to
|
||||
PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize.
|
||||
*/
|
||||
typedef struct PaWinUtilComInitializationResult{
|
||||
int state;
|
||||
int initializingThreadId;
|
||||
} PaWinUtilComInitializationResult;
|
||||
|
||||
|
||||
/**
|
||||
@brief Initialize Microsoft COM subsystem on the current thread.
|
||||
|
||||
@param hostApiType the host API type id of the caller. Used for error reporting.
|
||||
|
||||
@param comInitializationResult An output parameter. The value pointed to by
|
||||
this parameter stores information required by PaWinUtil_CoUninitialize
|
||||
to correctly uninitialize COM. The value should be retained and later
|
||||
passed to PaWinUtil_CoUninitialize.
|
||||
|
||||
If PaWinUtil_CoInitialize returns paNoError, the caller must later call
|
||||
PaWinUtil_CoUninitialize once.
|
||||
*/
|
||||
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult );
|
||||
|
||||
|
||||
/**
|
||||
@brief Uninitialize the Microsoft COM subsystem on the current thread using
|
||||
the result of a previous call to PaWinUtil_CoInitialize. Must be called on the same
|
||||
thread as PaWinUtil_CoInitialize.
|
||||
|
||||
@param hostApiType the host API type id of the caller. Used for error reporting.
|
||||
|
||||
@param comInitializationResult An input parameter. A pointer to a value previously
|
||||
initialized by a call to PaWinUtil_CoInitialize.
|
||||
*/
|
||||
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* PA_WIN_COINITIALIZE_H */
|
||||
/*
|
||||
* Microsoft COM initialization routines
|
||||
* Copyright (c) 1999-2011 Ross Bencina, 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 win_src
|
||||
|
||||
@brief Microsoft COM initialization routines.
|
||||
*/
|
||||
|
||||
#ifndef PA_WIN_COINITIALIZE_H
|
||||
#define PA_WIN_COINITIALIZE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/**
|
||||
@brief Data type used to hold the result of an attempt to initialize COM
|
||||
using PaWinUtil_CoInitialize. Must be retained between a call to
|
||||
PaWinUtil_CoInitialize and a matching call to PaWinUtil_CoUninitialize.
|
||||
*/
|
||||
typedef struct PaWinUtilComInitializationResult{
|
||||
int state;
|
||||
int initializingThreadId;
|
||||
} PaWinUtilComInitializationResult;
|
||||
|
||||
|
||||
/**
|
||||
@brief Initialize Microsoft COM subsystem on the current thread.
|
||||
|
||||
@param hostApiType the host API type id of the caller. Used for error reporting.
|
||||
|
||||
@param comInitializationResult An output parameter. The value pointed to by
|
||||
this parameter stores information required by PaWinUtil_CoUninitialize
|
||||
to correctly uninitialize COM. The value should be retained and later
|
||||
passed to PaWinUtil_CoUninitialize.
|
||||
|
||||
If PaWinUtil_CoInitialize returns paNoError, the caller must later call
|
||||
PaWinUtil_CoUninitialize once.
|
||||
*/
|
||||
PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult );
|
||||
|
||||
|
||||
/**
|
||||
@brief Uninitialize the Microsoft COM subsystem on the current thread using
|
||||
the result of a previous call to PaWinUtil_CoInitialize. Must be called on the same
|
||||
thread as PaWinUtil_CoInitialize.
|
||||
|
||||
@param hostApiType the host API type id of the caller. Used for error reporting.
|
||||
|
||||
@param comInitializationResult An input parameter. A pointer to a value previously
|
||||
initialized by a call to PaWinUtil_CoInitialize.
|
||||
*/
|
||||
void PaWinUtil_CoUninitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitializationResult *comInitializationResult );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* PA_WIN_COINITIALIZE_H */
|
||||
|
|
|
|||
|
|
@ -1,158 +1,158 @@
|
|||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Windows WAVEFORMAT* data structure utilities
|
||||
* portaudio.h should be included before this file.
|
||||
*
|
||||
* Copyright (c) 2007 Ross Bencina
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_waveformat.h"
|
||||
|
||||
|
||||
#if !defined(WAVE_FORMAT_EXTENSIBLE)
|
||||
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
|
||||
#endif
|
||||
|
||||
static GUID pawin_ksDataFormatSubtypeGuidBase =
|
||||
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
|
||||
|
||||
|
||||
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat )
|
||||
{
|
||||
if( sampleFormat == paFloat32 )
|
||||
return PAWIN_WAVE_FORMAT_IEEE_FLOAT;
|
||||
|
||||
return PAWIN_WAVE_FORMAT_PCM;
|
||||
}
|
||||
|
||||
|
||||
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
|
||||
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
|
||||
{
|
||||
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
|
||||
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
|
||||
unsigned long bytesPerFrame = numChannels * bytesPerSample;
|
||||
|
||||
waveFormatEx->wFormatTag = waveFormatTag;
|
||||
waveFormatEx->nChannels = (WORD)numChannels;
|
||||
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
|
||||
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
|
||||
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
|
||||
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
|
||||
waveFormatEx->cbSize = 0;
|
||||
}
|
||||
|
||||
|
||||
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
|
||||
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
|
||||
PaWinWaveFormatChannelMask channelMask )
|
||||
{
|
||||
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
|
||||
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
|
||||
unsigned long bytesPerFrame = numChannels * bytesPerSample;
|
||||
GUID guid;
|
||||
|
||||
waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
waveFormatEx->nChannels = (WORD)numChannels;
|
||||
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
|
||||
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
|
||||
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
|
||||
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
|
||||
waveFormatEx->cbSize = 22;
|
||||
|
||||
*((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) =
|
||||
waveFormatEx->wBitsPerSample;
|
||||
|
||||
*((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask;
|
||||
|
||||
guid = pawin_ksDataFormatSubtypeGuidBase;
|
||||
guid.Data1 = (USHORT)waveFormatTag;
|
||||
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
|
||||
}
|
||||
|
||||
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
|
||||
{
|
||||
switch( numChannels ){
|
||||
case 1:
|
||||
return PAWIN_SPEAKER_MONO;
|
||||
case 2:
|
||||
return PAWIN_SPEAKER_STEREO;
|
||||
case 3:
|
||||
return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT;
|
||||
case 4:
|
||||
return PAWIN_SPEAKER_QUAD;
|
||||
case 5:
|
||||
return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER;
|
||||
case 6:
|
||||
/* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time:
|
||||
http://msdn2.microsoft.com/en-us/library/aa474707.aspx
|
||||
We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND)
|
||||
because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND
|
||||
results in a virtual mixdown placing the rear output in the
|
||||
front _and_ rear speakers.
|
||||
*/
|
||||
return PAWIN_SPEAKER_5POINT1;
|
||||
/* case 7: */
|
||||
case 8:
|
||||
/* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio
|
||||
output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Micrsoft HD Audio driver using PAWIN_SPEAKER_7POINT1.
|
||||
With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */
|
||||
return PAWIN_SPEAKER_7POINT1_SURROUND;
|
||||
}
|
||||
|
||||
/* Apparently some Audigy drivers will output silence
|
||||
if the direct-out constant (0) is used. So this is not ideal.
|
||||
|
||||
RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal.
|
||||
*/
|
||||
return PAWIN_SPEAKER_DIRECTOUT;
|
||||
|
||||
/* Note that Alec Rogers proposed the following as an alternate method to
|
||||
generate the default channel mask, however it doesn't seem to be an improvement
|
||||
over the above, since some drivers will matrix outputs mapping to non-present
|
||||
speakers accross multiple physical speakers.
|
||||
|
||||
if(nChannels==1) {
|
||||
pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER;
|
||||
}
|
||||
else {
|
||||
pwfFormat->dwChannelMask = 0;
|
||||
for(i=0; i<nChannels; i++)
|
||||
pwfFormat->dwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Windows WAVEFORMAT* data structure utilities
|
||||
* portaudio.h should be included before this file.
|
||||
*
|
||||
* Copyright (c) 2007 Ross Bencina
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_waveformat.h"
|
||||
|
||||
|
||||
#if !defined(WAVE_FORMAT_EXTENSIBLE)
|
||||
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
|
||||
#endif
|
||||
|
||||
static GUID pawin_ksDataFormatSubtypeGuidBase =
|
||||
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
|
||||
|
||||
|
||||
int PaWin_SampleFormatToLinearWaveFormatTag( PaSampleFormat sampleFormat )
|
||||
{
|
||||
if( sampleFormat == paFloat32 )
|
||||
return PAWIN_WAVE_FORMAT_IEEE_FLOAT;
|
||||
|
||||
return PAWIN_WAVE_FORMAT_PCM;
|
||||
}
|
||||
|
||||
|
||||
void PaWin_InitializeWaveFormatEx( PaWinWaveFormat *waveFormat,
|
||||
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate )
|
||||
{
|
||||
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
|
||||
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
|
||||
unsigned long bytesPerFrame = numChannels * bytesPerSample;
|
||||
|
||||
waveFormatEx->wFormatTag = waveFormatTag;
|
||||
waveFormatEx->nChannels = (WORD)numChannels;
|
||||
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
|
||||
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
|
||||
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
|
||||
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
|
||||
waveFormatEx->cbSize = 0;
|
||||
}
|
||||
|
||||
|
||||
void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
|
||||
int numChannels, PaSampleFormat sampleFormat, int waveFormatTag, double sampleRate,
|
||||
PaWinWaveFormatChannelMask channelMask )
|
||||
{
|
||||
WAVEFORMATEX *waveFormatEx = (WAVEFORMATEX*)waveFormat;
|
||||
int bytesPerSample = Pa_GetSampleSize(sampleFormat);
|
||||
unsigned long bytesPerFrame = numChannels * bytesPerSample;
|
||||
GUID guid;
|
||||
|
||||
waveFormatEx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
waveFormatEx->nChannels = (WORD)numChannels;
|
||||
waveFormatEx->nSamplesPerSec = (DWORD)sampleRate;
|
||||
waveFormatEx->nAvgBytesPerSec = waveFormatEx->nSamplesPerSec * bytesPerFrame;
|
||||
waveFormatEx->nBlockAlign = (WORD)bytesPerFrame;
|
||||
waveFormatEx->wBitsPerSample = bytesPerSample * 8;
|
||||
waveFormatEx->cbSize = 22;
|
||||
|
||||
*((WORD*)&waveFormat->fields[PAWIN_INDEXOF_WVALIDBITSPERSAMPLE]) =
|
||||
waveFormatEx->wBitsPerSample;
|
||||
|
||||
*((DWORD*)&waveFormat->fields[PAWIN_INDEXOF_DWCHANNELMASK]) = channelMask;
|
||||
|
||||
guid = pawin_ksDataFormatSubtypeGuidBase;
|
||||
guid.Data1 = (USHORT)waveFormatTag;
|
||||
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
|
||||
}
|
||||
|
||||
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
|
||||
{
|
||||
switch( numChannels ){
|
||||
case 1:
|
||||
return PAWIN_SPEAKER_MONO;
|
||||
case 2:
|
||||
return PAWIN_SPEAKER_STEREO;
|
||||
case 3:
|
||||
return PAWIN_SPEAKER_FRONT_LEFT | PAWIN_SPEAKER_FRONT_CENTER | PAWIN_SPEAKER_FRONT_RIGHT;
|
||||
case 4:
|
||||
return PAWIN_SPEAKER_QUAD;
|
||||
case 5:
|
||||
return PAWIN_SPEAKER_QUAD | PAWIN_SPEAKER_FRONT_CENTER;
|
||||
case 6:
|
||||
/* The meaning of the PAWIN_SPEAKER_5POINT1 flag has changed over time:
|
||||
http://msdn2.microsoft.com/en-us/library/aa474707.aspx
|
||||
We use PAWIN_SPEAKER_5POINT1 (not PAWIN_SPEAKER_5POINT1_SURROUND)
|
||||
because on some cards (eg Audigy) PAWIN_SPEAKER_5POINT1_SURROUND
|
||||
results in a virtual mixdown placing the rear output in the
|
||||
front _and_ rear speakers.
|
||||
*/
|
||||
return PAWIN_SPEAKER_5POINT1;
|
||||
/* case 7: */
|
||||
case 8:
|
||||
/* RoBi: PAWIN_SPEAKER_7POINT1_SURROUND fits normal surround sound setups better than PAWIN_SPEAKER_7POINT1, f.i. NVidia HDMI Audio
|
||||
output is silent on channels 5&6 with NVidia drivers, and channel 7&8 with Micrsoft HD Audio driver using PAWIN_SPEAKER_7POINT1.
|
||||
With PAWIN_SPEAKER_7POINT1_SURROUND both setups work OK. */
|
||||
return PAWIN_SPEAKER_7POINT1_SURROUND;
|
||||
}
|
||||
|
||||
/* Apparently some Audigy drivers will output silence
|
||||
if the direct-out constant (0) is used. So this is not ideal.
|
||||
|
||||
RoBi 2012-12-19: Also, NVidia driver seem to output garbage instead. Again not very ideal.
|
||||
*/
|
||||
return PAWIN_SPEAKER_DIRECTOUT;
|
||||
|
||||
/* Note that Alec Rogers proposed the following as an alternate method to
|
||||
generate the default channel mask, however it doesn't seem to be an improvement
|
||||
over the above, since some drivers will matrix outputs mapping to non-present
|
||||
speakers accross multiple physical speakers.
|
||||
|
||||
if(nChannels==1) {
|
||||
pwfFormat->dwChannelMask = SPEAKER_FRONT_CENTER;
|
||||
}
|
||||
else {
|
||||
pwfFormat->dwChannelMask = 0;
|
||||
for(i=0; i<nChannels; i++)
|
||||
pwfFormat->dwChannelMask = (pwfFormat->dwChannelMask << 1) | 0x1;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,309 +1,309 @@
|
|||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Windows WDM KS utilities
|
||||
*
|
||||
* Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <mmreg.h>
|
||||
#ifndef WAVE_FORMAT_IEEE_FLOAT
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this
|
||||
#endif
|
||||
#ifndef _WAVEFORMATEXTENSIBLE_
|
||||
#define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this
|
||||
#endif
|
||||
#ifndef _INC_MMREG
|
||||
#define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
#endif
|
||||
#include <winioctl.h> // MinGW32 does not define this automatically
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#include "../../hostapi/wasapi/mingw-include/ks.h"
|
||||
#include "../../hostapi/wasapi/mingw-include/ksmedia.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // just for some development printfs
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_win_wdmks_utils.h"
|
||||
|
||||
|
||||
/* PortAudio-local instances of GUIDs previously sourced from ksguid.lib */
|
||||
|
||||
/* GUID KSDATAFORMAT_TYPE_AUDIO */
|
||||
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
|
||||
|
||||
/* GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT */
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
|
||||
|
||||
/* GUID KSDATAFORMAT_SUBTYPE_PCM */
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
|
||||
|
||||
/* GUID KSDATAFORMAT_SUBTYPE_WAVEFORMATEX */
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
|
||||
|
||||
/* GUID KSMEDIUMSETID_Standard */
|
||||
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
|
||||
|
||||
/* GUID KSINTERFACESETID_Standard */
|
||||
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
|
||||
|
||||
/* GUID KSPROPSETID_Pin */
|
||||
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
|
||||
|
||||
#define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\
|
||||
(!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
|
||||
|
||||
|
||||
static PaError WdmGetPinPropertySimple(
|
||||
HANDLE handle,
|
||||
unsigned long pinId,
|
||||
unsigned long property,
|
||||
void* value,
|
||||
unsigned long valueSize )
|
||||
{
|
||||
DWORD bytesReturned;
|
||||
KSP_PIN ksPProp;
|
||||
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
|
||||
ksPProp.Property.Id = property;
|
||||
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
ksPProp.PinId = pinId;
|
||||
ksPProp.Reserved = 0;
|
||||
|
||||
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
|
||||
value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize )
|
||||
{
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
else
|
||||
{
|
||||
return paNoError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static PaError WdmGetPinPropertyMulti(
|
||||
HANDLE handle,
|
||||
unsigned long pinId,
|
||||
unsigned long property,
|
||||
KSMULTIPLE_ITEM** ksMultipleItem)
|
||||
{
|
||||
unsigned long multipleItemSize = 0;
|
||||
KSP_PIN ksPProp;
|
||||
DWORD bytesReturned;
|
||||
|
||||
*ksMultipleItem = 0;
|
||||
|
||||
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
|
||||
ksPProp.Property.Id = property;
|
||||
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
ksPProp.PinId = pinId;
|
||||
ksPProp.Reserved = 0;
|
||||
|
||||
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property,
|
||||
sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA )
|
||||
{
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
|
||||
*ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
|
||||
if( !*ksMultipleItem )
|
||||
{
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
|
||||
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
|
||||
(void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize )
|
||||
{
|
||||
PaUtil_FreeMemory( ksMultipleItem );
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
|
||||
static int GetKSFilterPinCount( HANDLE deviceHandle )
|
||||
{
|
||||
DWORD result;
|
||||
|
||||
if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){
|
||||
return result;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId )
|
||||
{
|
||||
KSPIN_COMMUNICATION result;
|
||||
|
||||
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){
|
||||
return result;
|
||||
}else{
|
||||
return KSPIN_COMMUNICATION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId )
|
||||
{
|
||||
KSPIN_DATAFLOW result;
|
||||
|
||||
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){
|
||||
return result;
|
||||
}else{
|
||||
return (KSPIN_DATAFLOW)0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int KSFilterPinPropertyIdentifiersInclude(
|
||||
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
|
||||
{
|
||||
KSMULTIPLE_ITEM* item = NULL;
|
||||
KSIDENTIFIER* identifier;
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
|
||||
return 0;
|
||||
|
||||
identifier = (KSIDENTIFIER*)(item+1);
|
||||
|
||||
for( i = 0; i < (int)item->Count; i++ )
|
||||
{
|
||||
if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) &&
|
||||
( identifier[i].Id == identifierId ) )
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PaUtil_FreeMemory( item );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* return the maximum channel count supported by any pin on the device.
|
||||
if isInput is non-zero we query input pins, otherwise output pins.
|
||||
*/
|
||||
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput )
|
||||
{
|
||||
HANDLE deviceHandle;
|
||||
ULONG i;
|
||||
int pinCount, pinId;
|
||||
int result = 0;
|
||||
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
|
||||
|
||||
if( !wcharDevicePath )
|
||||
return 0;
|
||||
|
||||
deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
|
||||
if( deviceHandle == INVALID_HANDLE_VALUE )
|
||||
return 0;
|
||||
|
||||
pinCount = GetKSFilterPinCount( deviceHandle );
|
||||
for( pinId = 0; pinId < pinCount; ++pinId )
|
||||
{
|
||||
KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId );
|
||||
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
|
||||
if( ( dataflow == requiredDataflowDirection ) &&
|
||||
(( communication == KSPIN_COMMUNICATION_SINK) ||
|
||||
( communication == KSPIN_COMMUNICATION_BOTH))
|
||||
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
|
||||
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
|
||||
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
|
||||
{
|
||||
KSMULTIPLE_ITEM* item = NULL;
|
||||
if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError )
|
||||
{
|
||||
KSDATARANGE *dataRange = (KSDATARANGE*)(item+1);
|
||||
|
||||
for( i=0; i < item->Count; ++i ){
|
||||
|
||||
if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat)
|
||||
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0
|
||||
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0
|
||||
|| ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 )
|
||||
&& ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) )
|
||||
{
|
||||
KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange;
|
||||
|
||||
/*
|
||||
printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath );
|
||||
|
||||
if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 )
|
||||
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" );
|
||||
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 )
|
||||
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" );
|
||||
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 )
|
||||
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" );
|
||||
else
|
||||
printf( "\tspecifier: ?\n" );
|
||||
*/
|
||||
|
||||
/*
|
||||
We assume that very high values for MaximumChannels are not useful and indicate
|
||||
that the driver isn't prepared to tell us the real number of channels which it supports.
|
||||
*/
|
||||
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
|
||||
result = (int)dataRangeAudio->MaximumChannels;
|
||||
}
|
||||
|
||||
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
|
||||
}
|
||||
|
||||
PaUtil_FreeMemory( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle( deviceHandle );
|
||||
return result;
|
||||
}
|
||||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Windows WDM KS utilities
|
||||
*
|
||||
* Copyright (c) 1999 - 2007 Andrew Baldwin, Ross Bencina
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <mmreg.h>
|
||||
#ifndef WAVE_FORMAT_IEEE_FLOAT
|
||||
#define WAVE_FORMAT_IEEE_FLOAT 0x0003 // MinGW32 does not define this
|
||||
#endif
|
||||
#ifndef _WAVEFORMATEXTENSIBLE_
|
||||
#define _WAVEFORMATEXTENSIBLE_ // MinGW32 does not define this
|
||||
#endif
|
||||
#ifndef _INC_MMREG
|
||||
#define _INC_MMREG // for STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
#endif
|
||||
#include <winioctl.h> // MinGW32 does not define this automatically
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#include "../../hostapi/wasapi/mingw-include/ks.h"
|
||||
#include "../../hostapi/wasapi/mingw-include/ksmedia.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h> // just for some development printfs
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_win_wdmks_utils.h"
|
||||
|
||||
|
||||
/* PortAudio-local instances of GUIDs previously sourced from ksguid.lib */
|
||||
|
||||
/* GUID KSDATAFORMAT_TYPE_AUDIO */
|
||||
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
|
||||
|
||||
/* GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT */
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
|
||||
|
||||
/* GUID KSDATAFORMAT_SUBTYPE_PCM */
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
|
||||
|
||||
/* GUID KSDATAFORMAT_SUBTYPE_WAVEFORMATEX */
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
|
||||
|
||||
/* GUID KSMEDIUMSETID_Standard */
|
||||
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
|
||||
|
||||
/* GUID KSINTERFACESETID_Standard */
|
||||
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
|
||||
|
||||
/* GUID KSPROPSETID_Pin */
|
||||
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
|
||||
|
||||
#define pa_IS_VALID_WAVEFORMATEX_GUID(Guid)\
|
||||
(!memcmp(((PUSHORT)&pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX) + 1, ((PUSHORT)(Guid)) + 1, sizeof(GUID) - sizeof(USHORT)))
|
||||
|
||||
|
||||
static PaError WdmGetPinPropertySimple(
|
||||
HANDLE handle,
|
||||
unsigned long pinId,
|
||||
unsigned long property,
|
||||
void* value,
|
||||
unsigned long valueSize )
|
||||
{
|
||||
DWORD bytesReturned;
|
||||
KSP_PIN ksPProp;
|
||||
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
|
||||
ksPProp.Property.Id = property;
|
||||
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
ksPProp.PinId = pinId;
|
||||
ksPProp.Reserved = 0;
|
||||
|
||||
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
|
||||
value, valueSize, &bytesReturned, NULL ) == 0 || bytesReturned != valueSize )
|
||||
{
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
else
|
||||
{
|
||||
return paNoError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static PaError WdmGetPinPropertyMulti(
|
||||
HANDLE handle,
|
||||
unsigned long pinId,
|
||||
unsigned long property,
|
||||
KSMULTIPLE_ITEM** ksMultipleItem)
|
||||
{
|
||||
unsigned long multipleItemSize = 0;
|
||||
KSP_PIN ksPProp;
|
||||
DWORD bytesReturned;
|
||||
|
||||
*ksMultipleItem = 0;
|
||||
|
||||
ksPProp.Property.Set = pa_KSPROPSETID_Pin;
|
||||
ksPProp.Property.Id = property;
|
||||
ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
ksPProp.PinId = pinId;
|
||||
ksPProp.Reserved = 0;
|
||||
|
||||
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp.Property,
|
||||
sizeof(KSP_PIN), NULL, 0, &multipleItemSize, NULL ) == 0 && GetLastError() != ERROR_MORE_DATA )
|
||||
{
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
|
||||
*ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
|
||||
if( !*ksMultipleItem )
|
||||
{
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
|
||||
if( DeviceIoControl( handle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN),
|
||||
(void*)*ksMultipleItem, multipleItemSize, &bytesReturned, NULL ) == 0 || bytesReturned != multipleItemSize )
|
||||
{
|
||||
PaUtil_FreeMemory( ksMultipleItem );
|
||||
return paUnanticipatedHostError;
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
|
||||
static int GetKSFilterPinCount( HANDLE deviceHandle )
|
||||
{
|
||||
DWORD result;
|
||||
|
||||
if( WdmGetPinPropertySimple( deviceHandle, 0, KSPROPERTY_PIN_CTYPES, &result, sizeof(result) ) == paNoError ){
|
||||
return result;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static KSPIN_COMMUNICATION GetKSFilterPinPropertyCommunication( HANDLE deviceHandle, int pinId )
|
||||
{
|
||||
KSPIN_COMMUNICATION result;
|
||||
|
||||
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_COMMUNICATION, &result, sizeof(result) ) == paNoError ){
|
||||
return result;
|
||||
}else{
|
||||
return KSPIN_COMMUNICATION_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static KSPIN_DATAFLOW GetKSFilterPinPropertyDataflow( HANDLE deviceHandle, int pinId )
|
||||
{
|
||||
KSPIN_DATAFLOW result;
|
||||
|
||||
if( WdmGetPinPropertySimple( deviceHandle, pinId, KSPROPERTY_PIN_DATAFLOW, &result, sizeof(result) ) == paNoError ){
|
||||
return result;
|
||||
}else{
|
||||
return (KSPIN_DATAFLOW)0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int KSFilterPinPropertyIdentifiersInclude(
|
||||
HANDLE deviceHandle, int pinId, unsigned long property, const GUID *identifierSet, unsigned long identifierId )
|
||||
{
|
||||
KSMULTIPLE_ITEM* item = NULL;
|
||||
KSIDENTIFIER* identifier;
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
if( WdmGetPinPropertyMulti( deviceHandle, pinId, property, &item) != paNoError )
|
||||
return 0;
|
||||
|
||||
identifier = (KSIDENTIFIER*)(item+1);
|
||||
|
||||
for( i = 0; i < (int)item->Count; i++ )
|
||||
{
|
||||
if( !memcmp( (void*)&identifier[i].Set, (void*)identifierSet, sizeof( GUID ) ) &&
|
||||
( identifier[i].Id == identifierId ) )
|
||||
{
|
||||
result = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PaUtil_FreeMemory( item );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* return the maximum channel count supported by any pin on the device.
|
||||
if isInput is non-zero we query input pins, otherwise output pins.
|
||||
*/
|
||||
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput )
|
||||
{
|
||||
HANDLE deviceHandle;
|
||||
ULONG i;
|
||||
int pinCount, pinId;
|
||||
int result = 0;
|
||||
KSPIN_DATAFLOW requiredDataflowDirection = (isInput ? KSPIN_DATAFLOW_OUT : KSPIN_DATAFLOW_IN );
|
||||
|
||||
if( !wcharDevicePath )
|
||||
return 0;
|
||||
|
||||
deviceHandle = CreateFileW( (LPCWSTR)wcharDevicePath, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL );
|
||||
if( deviceHandle == INVALID_HANDLE_VALUE )
|
||||
return 0;
|
||||
|
||||
pinCount = GetKSFilterPinCount( deviceHandle );
|
||||
for( pinId = 0; pinId < pinCount; ++pinId )
|
||||
{
|
||||
KSPIN_COMMUNICATION communication = GetKSFilterPinPropertyCommunication( deviceHandle, pinId );
|
||||
KSPIN_DATAFLOW dataflow = GetKSFilterPinPropertyDataflow( deviceHandle, pinId );
|
||||
if( ( dataflow == requiredDataflowDirection ) &&
|
||||
(( communication == KSPIN_COMMUNICATION_SINK) ||
|
||||
( communication == KSPIN_COMMUNICATION_BOTH))
|
||||
&& ( KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_STREAMING )
|
||||
|| KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_INTERFACES, &pa_KSINTERFACESETID_Standard, KSINTERFACE_STANDARD_LOOPED_STREAMING ) )
|
||||
&& KSFilterPinPropertyIdentifiersInclude( deviceHandle, pinId,
|
||||
KSPROPERTY_PIN_MEDIUMS, &pa_KSMEDIUMSETID_Standard, KSMEDIUM_STANDARD_DEVIO ) )
|
||||
{
|
||||
KSMULTIPLE_ITEM* item = NULL;
|
||||
if( WdmGetPinPropertyMulti( deviceHandle, pinId, KSPROPERTY_PIN_DATARANGES, &item ) == paNoError )
|
||||
{
|
||||
KSDATARANGE *dataRange = (KSDATARANGE*)(item+1);
|
||||
|
||||
for( i=0; i < item->Count; ++i ){
|
||||
|
||||
if( pa_IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat)
|
||||
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) == 0
|
||||
|| memcmp( (void*)&dataRange->SubFormat, (void*)&pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) == 0
|
||||
|| ( ( memcmp( (void*)&dataRange->MajorFormat, (void*)&pa_KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID) ) == 0 )
|
||||
&& ( memcmp( (void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) == 0 ) ) )
|
||||
{
|
||||
KSDATARANGE_AUDIO *dataRangeAudio = (KSDATARANGE_AUDIO*)dataRange;
|
||||
|
||||
/*
|
||||
printf( ">>> %d %d %d %d %S\n", isInput, dataflow, communication, dataRangeAudio->MaximumChannels, devicePath );
|
||||
|
||||
if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) ) == 0 )
|
||||
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WAVEFORMATEX\n" );
|
||||
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_DSOUND, sizeof(GUID) ) == 0 )
|
||||
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_DSOUND\n" );
|
||||
else if( memcmp((void*)&dataRange->Specifier, (void*)&KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID) ) == 0 )
|
||||
printf( "\tspecifier: KSDATAFORMAT_SPECIFIER_WILDCARD\n" );
|
||||
else
|
||||
printf( "\tspecifier: ?\n" );
|
||||
*/
|
||||
|
||||
/*
|
||||
We assume that very high values for MaximumChannels are not useful and indicate
|
||||
that the driver isn't prepared to tell us the real number of channels which it supports.
|
||||
*/
|
||||
if( dataRangeAudio->MaximumChannels < 0xFFFFUL && (int)dataRangeAudio->MaximumChannels > result )
|
||||
result = (int)dataRangeAudio->MaximumChannels;
|
||||
}
|
||||
|
||||
dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
|
||||
}
|
||||
|
||||
PaUtil_FreeMemory( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle( deviceHandle );
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +1,65 @@
|
|||
#ifndef PA_WIN_WDMKS_UTILS_H
|
||||
#define PA_WIN_WDMKS_UTILS_H
|
||||
|
||||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Windows WDM KS utilities
|
||||
*
|
||||
* Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin
|
||||
*
|
||||
* 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
|
||||
@brief Utilities for working with the Windows WDM KS API
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Query for the maximum number of channels supported by any pin of the
|
||||
specified device. Returns 0 if the query fails for any reason.
|
||||
|
||||
@param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string.
|
||||
Declard as void* to avoid introducing a dependency on wchar_t here.
|
||||
|
||||
@param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels.
|
||||
*/
|
||||
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifndef PA_WIN_WDMKS_UTILS_H
|
||||
#define PA_WIN_WDMKS_UTILS_H
|
||||
|
||||
/*
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Windows WDM KS utilities
|
||||
*
|
||||
* Copyright (c) 1999 - 2007 Ross Bencina, Andrew Baldwin
|
||||
*
|
||||
* 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
|
||||
@brief Utilities for working with the Windows WDM KS API
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Query for the maximum number of channels supported by any pin of the
|
||||
specified device. Returns 0 if the query fails for any reason.
|
||||
|
||||
@param wcharDevicePath A system level PnP interface path, supplied as a WCHAR unicode string.
|
||||
Declard as void* to avoid introducing a dependency on wchar_t here.
|
||||
|
||||
@param isInput A flag specifying whether to query for input (non-zero) or output (zero) channels.
|
||||
*/
|
||||
int PaWin_WDMKS_QueryFilterMaximumChannelCount( void *wcharDevicePath, int isInput );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* PA_WIN_WDMKS_UTILS_H */
|
||||
Loading…
Reference in a new issue