PortAudio: Update to v190600_20161030
This commit is contained in:
parent
b05fc9d369
commit
3dc7d18775
|
@ -137,6 +137,8 @@ IF(WIN32)
|
|||
SET(PA_PRIVATE_INCLUDES ${PA_PRIVATE_INCLUDES} ${PA_PLATFORM_INCLUDES})
|
||||
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} src/os/win)
|
||||
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} winmm)
|
||||
|
||||
# Try to find ASIO SDK (assumes that portaudio and asiosdk folders are side-by-side, see
|
||||
# http://www.portaudio.com/trac/wiki/TutorialDir/Compile/WindowsASIOMSVC)
|
||||
FIND_PACKAGE(ASIOSDK)
|
||||
|
@ -156,7 +158,7 @@ IF(WIN32)
|
|||
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_asio.h)
|
||||
SET(PA_SOURCES ${PA_SOURCES} ${PA_ASIO_SOURCES})
|
||||
SET(PA_NON_UNICODE_SOURCES ${PA_NON_UNICODE_SOURCES} ${PA_ASIOSDK_SOURCES})
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} winmm ole32 uuid)
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ole32 uuid)
|
||||
ELSE()
|
||||
# Set variables for DEF file expansion
|
||||
SET(DEF_EXCLUDE_ASIO_SYMBOLS ";")
|
||||
|
@ -195,6 +197,7 @@ IF(WIN32)
|
|||
SOURCE_GROUP("hostapi\\wmme" FILES ${PA_WMME_SOURCES})
|
||||
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_wmme.h)
|
||||
SET(PA_SOURCES ${PA_SOURCES} ${PA_WMME_SOURCES})
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ole32 uuid)
|
||||
ENDIF()
|
||||
|
||||
IF(MSVS)
|
||||
|
@ -209,6 +212,7 @@ IF(WIN32)
|
|||
SOURCE_GROUP("hostapi\\wasapi" FILES ${PA_WASAPI_SOURCES})
|
||||
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_wasapi.h)
|
||||
SET(PA_SOURCES ${PA_SOURCES} ${PA_WASAPI_SOURCES})
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} ole32 uuid)
|
||||
IF(NOT MSVC)
|
||||
SET(PA_PRIVATE_INCLUDE_PATHS ${PA_PRIVATE_INCLUDE_PATHS} src/hostapi/wasapi/mingw-include)
|
||||
ENDIF()
|
||||
|
@ -222,8 +226,7 @@ IF(WIN32)
|
|||
SOURCE_GROUP("hostapi\\wdmks" FILES ${PA_WDMKS_SOURCES})
|
||||
SET(PA_PUBLIC_INCLUDES ${PA_PUBLIC_INCLUDES} include/pa_win_wdmks.h)
|
||||
SET(PA_SOURCES ${PA_SOURCES} ${PA_WDMKS_SOURCES})
|
||||
# If we use WDM/KS we need setupapi.lib
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} setupapi)
|
||||
SET(PA_LIBRARY_DEPENDENCIES ${PA_LIBRARY_DEPENDENCIES} setupapi ole32 uuid)
|
||||
ENDIF()
|
||||
|
||||
OPTION(PA_USE_WDMKS_DEVICE_INFO "Use WDM/KS API for device info" ON)
|
||||
|
@ -250,7 +253,7 @@ ELSE()
|
|||
|
||||
IF(APPLE)
|
||||
|
||||
# SET(CMAKE_MACOSX_RPATH 1)
|
||||
SET(CMAKE_MACOSX_RPATH 1)
|
||||
OPTION(PA_USE_COREAUDIO "Enable support for CoreAudio" ON)
|
||||
IF(PA_USE_COREAUDIO)
|
||||
SET(PA_COREAUDIO_SOURCES
|
||||
|
@ -344,14 +347,14 @@ ENDIF()
|
|||
|
||||
ADD_LIBRARY(portaudio SHARED ${PA_INCLUDES} ${PA_COMMON_INCLUDES} ${PA_SOURCES} ${PA_NON_UNICODE_SOURCES} ${PA_EXTRA_SHARED_SOURCES})
|
||||
SET_PROPERTY(TARGET portaudio APPEND_STRING PROPERTY COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS})
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio PRIVATE ${PA_PRIVATE_INCLUDE_PATHS})
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio PUBLIC include)
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio BEFORE PRIVATE ${PA_PRIVATE_INCLUDE_PATHS})
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio BEFORE PUBLIC include)
|
||||
TARGET_LINK_LIBRARIES(portaudio ${PA_LIBRARY_DEPENDENCIES})
|
||||
|
||||
ADD_LIBRARY(portaudio_static STATIC ${PA_INCLUDES} ${PA_COMMON_INCLUDES} ${PA_SOURCES} ${PA_NON_UNICODE_SOURCES})
|
||||
SET_PROPERTY(TARGET portaudio_static APPEND_STRING PROPERTY COMPILE_DEFINITIONS ${PA_PRIVATE_COMPILE_DEFINITIONS})
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio_static PRIVATE ${PA_PRIVATE_INCLUDE_PATHS})
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio_static PUBLIC include)
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio_static BEFORE PRIVATE ${PA_PRIVATE_INCLUDE_PATHS})
|
||||
TARGET_INCLUDE_DIRECTORIES(portaudio_static BEFORE PUBLIC include)
|
||||
TARGET_LINK_LIBRARIES(portaudio_static ${PA_LIBRARY_DEPENDENCIES})
|
||||
|
||||
IF(WIN32 AND MSVC)
|
||||
|
@ -402,3 +405,4 @@ OPTION(PA_BUILD_EXAMPLES "Include example projects" OFF)
|
|||
IF(PA_BUILD_EXAMPLES)
|
||||
SUBDIRS(examples)
|
||||
ENDIF()
|
||||
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
; $Id: $
|
||||
;
|
||||
; !!! @GENERATED_MESSAGE@ !!!
|
||||
EXPORTS
|
||||
|
||||
;
|
||||
Pa_GetVersion @1
|
||||
Pa_GetVersionText @2
|
||||
Pa_GetErrorText @3
|
||||
Pa_Initialize @4
|
||||
Pa_Terminate @5
|
||||
Pa_GetHostApiCount @6
|
||||
Pa_GetDefaultHostApi @7
|
||||
Pa_GetHostApiInfo @8
|
||||
Pa_HostApiTypeIdToHostApiIndex @9
|
||||
Pa_HostApiDeviceIndexToDeviceIndex @10
|
||||
Pa_GetLastHostErrorInfo @11
|
||||
Pa_GetDeviceCount @12
|
||||
Pa_GetDefaultInputDevice @13
|
||||
Pa_GetDefaultOutputDevice @14
|
||||
Pa_GetDeviceInfo @15
|
||||
Pa_IsFormatSupported @16
|
||||
Pa_OpenStream @17
|
||||
Pa_OpenDefaultStream @18
|
||||
Pa_CloseStream @19
|
||||
Pa_SetStreamFinishedCallback @20
|
||||
Pa_StartStream @21
|
||||
Pa_StopStream @22
|
||||
Pa_AbortStream @23
|
||||
Pa_IsStreamStopped @24
|
||||
Pa_IsStreamActive @25
|
||||
Pa_GetStreamInfo @26
|
||||
Pa_GetStreamTime @27
|
||||
Pa_GetStreamCpuLoad @28
|
||||
Pa_ReadStream @29
|
||||
Pa_WriteStream @30
|
||||
Pa_GetStreamReadAvailable @31
|
||||
Pa_GetStreamWriteAvailable @32
|
||||
Pa_GetSampleSize @33
|
||||
Pa_Sleep @34
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetAvailableBufferSizes @50
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_ShowControlPanel @51
|
||||
@DEF_EXCLUDE_X86_PLAIN_CONVERTERS@PaUtil_InitializeX86PlainConverters @52
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetInputChannelName @53
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetOutputChannelName @54
|
||||
PaUtil_SetDebugPrintFunction @55
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetDeviceDefaultFormat @56
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetDeviceRole @57
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_ThreadPriorityBoost @58
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_ThreadPriorityRevert @59
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetFramesPerHostBuffer @60
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetJackDescription @61
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetJackCount @62
|
||||
; $Id: $
|
||||
;
|
||||
; !!! @GENERATED_MESSAGE@ !!!
|
||||
EXPORTS
|
||||
|
||||
;
|
||||
Pa_GetVersion @1
|
||||
Pa_GetVersionText @2
|
||||
Pa_GetErrorText @3
|
||||
Pa_Initialize @4
|
||||
Pa_Terminate @5
|
||||
Pa_GetHostApiCount @6
|
||||
Pa_GetDefaultHostApi @7
|
||||
Pa_GetHostApiInfo @8
|
||||
Pa_HostApiTypeIdToHostApiIndex @9
|
||||
Pa_HostApiDeviceIndexToDeviceIndex @10
|
||||
Pa_GetLastHostErrorInfo @11
|
||||
Pa_GetDeviceCount @12
|
||||
Pa_GetDefaultInputDevice @13
|
||||
Pa_GetDefaultOutputDevice @14
|
||||
Pa_GetDeviceInfo @15
|
||||
Pa_IsFormatSupported @16
|
||||
Pa_OpenStream @17
|
||||
Pa_OpenDefaultStream @18
|
||||
Pa_CloseStream @19
|
||||
Pa_SetStreamFinishedCallback @20
|
||||
Pa_StartStream @21
|
||||
Pa_StopStream @22
|
||||
Pa_AbortStream @23
|
||||
Pa_IsStreamStopped @24
|
||||
Pa_IsStreamActive @25
|
||||
Pa_GetStreamInfo @26
|
||||
Pa_GetStreamTime @27
|
||||
Pa_GetStreamCpuLoad @28
|
||||
Pa_ReadStream @29
|
||||
Pa_WriteStream @30
|
||||
Pa_GetStreamReadAvailable @31
|
||||
Pa_GetStreamWriteAvailable @32
|
||||
Pa_GetSampleSize @33
|
||||
Pa_Sleep @34
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetAvailableBufferSizes @50
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_ShowControlPanel @51
|
||||
@DEF_EXCLUDE_X86_PLAIN_CONVERTERS@PaUtil_InitializeX86PlainConverters @52
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetInputChannelName @53
|
||||
@DEF_EXCLUDE_ASIO_SYMBOLS@PaAsio_GetOutputChannelName @54
|
||||
PaUtil_SetDebugPrintFunction @55
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetDeviceDefaultFormat @56
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetDeviceRole @57
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_ThreadPriorityBoost @58
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_ThreadPriorityRevert @59
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetFramesPerHostBuffer @60
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetJackDescription @61
|
||||
@DEF_EXCLUDE_WASAPI_SYMBOLS@PaWasapi_GetJackCount @62
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_ASIO_H
|
||||
#define PA_ASIO_H
|
||||
/*
|
||||
* $Id: pa_asio.h 1667 2011-05-02 15:49:20Z rossb $
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* ASIO specific extensions
|
||||
*
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define PA_LINUX_ALSA_H
|
||||
|
||||
/*
|
||||
* $Id: pa_linux_alsa.h 1597 2011-02-11 00:15:51Z dmitrykos $
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* ALSA-specific extensions
|
||||
*
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include "portaudio.h"
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
//#include <AudioToolbox/AudioToolbox.h>
|
||||
#include <AudioToolbox/AudioToolbox.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -124,6 +124,19 @@ AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s );
|
|||
*/
|
||||
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input );
|
||||
|
||||
|
||||
/** Retrieve the range of legal native buffer sizes for the specificed device, in sample frames.
|
||||
|
||||
@param device The global index of the PortAudio device about which the query is being made.
|
||||
@param minBufferSizeFrames A pointer to the location which will receive the minimum buffer size value.
|
||||
@param maxBufferSizeFrames A pointer to the location which will receive the maximum buffer size value.
|
||||
|
||||
@see kAudioDevicePropertyBufferFrameSizeRange in the CoreAudio SDK.
|
||||
*/
|
||||
PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device,
|
||||
long *minBufferSizeFrames, long *maxBufferSizeFrames );
|
||||
|
||||
|
||||
/**
|
||||
* Flags
|
||||
*/
|
||||
|
|
|
@ -61,24 +61,21 @@ typedef struct PaWinDirectSoundStreamInfo{
|
|||
PaHostApiTypeId hostApiType; /**< paDirectSound */
|
||||
unsigned long version; /**< 2 */
|
||||
|
||||
unsigned long flags;
|
||||
unsigned long flags; /**< enable other features of this struct */
|
||||
|
||||
/* low-level latency setting support
|
||||
Control the size of host buffers in order to set latency. They will
|
||||
be used instead of the generic parameters to Pa_OpenStream() if
|
||||
flags contains the paWinDirectSoundUseLowLevelLatencyParameters
|
||||
flag.
|
||||
/**
|
||||
low-level latency setting support
|
||||
Sets the size of the DirectSound host buffer.
|
||||
When flags contains the paWinDirectSoundUseLowLevelLatencyParameters
|
||||
this size will be used instead of interpreting the generic latency
|
||||
parameters to Pa_OpenStream(). If the flag is not set this value is ignored.
|
||||
|
||||
If PaWinDirectSoundStreamInfo structures with paWinDirectSoundUseLowLevelLatencyParameters
|
||||
are supplied for both input and output in a full duplex stream, then the
|
||||
input and output framesPerBuffer must be the same, or the larger of the
|
||||
two must be a multiple of the smaller, otherwise a
|
||||
paIncompatibleHostApiSpecificStreamInfo error will be returned from
|
||||
Pa_OpenStream().
|
||||
If the stream is a full duplex stream the implementation requires that
|
||||
the values of framesPerBuffer for input and output match (if both are specified).
|
||||
*/
|
||||
unsigned long framesPerBuffer; /* NOT IMPLEMENTED see http://www.portaudio.com/trac/ticket/129 */
|
||||
unsigned long framesPerBuffer;
|
||||
|
||||
/*
|
||||
/**
|
||||
support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
|
||||
paWinDirectSoundUseChannelMask this allows you to specify which speakers
|
||||
to address in a multichannel stream. Constants for channelMask
|
||||
|
|
|
@ -69,8 +69,8 @@ typedef enum PaWasapiFlags
|
|||
method can only provide 15-20ms latency. */
|
||||
paWinWasapiPolling = (1 << 3),
|
||||
|
||||
/* forces custom thread priority setting. must be used if PaWasapiStreamInfo::threadPriority
|
||||
is set to custom value. */
|
||||
/* forces custom thread priority setting, must be used if PaWasapiStreamInfo::threadPriority
|
||||
is set to a custom value */
|
||||
paWinWasapiThreadPriority = (1 << 4)
|
||||
}
|
||||
PaWasapiFlags;
|
||||
|
@ -91,7 +91,7 @@ typedef void (*PaWasapiHostProcessorCallback) (void *inputBuffer, long inputFra
|
|||
void *outputBuffer, long outputFrames,
|
||||
void *userData);
|
||||
|
||||
/* Device role */
|
||||
/* Device role. */
|
||||
typedef enum PaWasapiDeviceRole
|
||||
{
|
||||
eRoleRemoteNetworkDevice = 0,
|
||||
|
@ -109,7 +109,7 @@ typedef enum PaWasapiDeviceRole
|
|||
PaWasapiDeviceRole;
|
||||
|
||||
|
||||
/* Jack connection type */
|
||||
/* Jack connection type. */
|
||||
typedef enum PaWasapiJackConnectionType
|
||||
{
|
||||
eJackConnTypeUnknown,
|
||||
|
@ -128,10 +128,10 @@ typedef enum PaWasapiJackConnectionType
|
|||
PaWasapiJackConnectionType;
|
||||
|
||||
|
||||
/* Jack geometric location */
|
||||
/* Jack geometric location. */
|
||||
typedef enum PaWasapiJackGeoLocation
|
||||
{
|
||||
eJackGeoLocUnk = 0,
|
||||
eJackGeoLocUnk = 0,
|
||||
eJackGeoLocRear = 0x1, /* matches EPcxGeoLocation::eGeoLocRear */
|
||||
eJackGeoLocFront,
|
||||
eJackGeoLocLeft,
|
||||
|
@ -151,7 +151,7 @@ typedef enum PaWasapiJackGeoLocation
|
|||
PaWasapiJackGeoLocation;
|
||||
|
||||
|
||||
/* Jack general location */
|
||||
/* Jack general location. */
|
||||
typedef enum PaWasapiJackGenLocation
|
||||
{
|
||||
eJackGenLocPrimaryBox = 0,
|
||||
|
@ -162,7 +162,7 @@ typedef enum PaWasapiJackGenLocation
|
|||
PaWasapiJackGenLocation;
|
||||
|
||||
|
||||
/* Jack's type of port */
|
||||
/* Jack's type of port. */
|
||||
typedef enum PaWasapiJackPortConnection
|
||||
{
|
||||
eJackPortConnJack = 0,
|
||||
|
@ -173,7 +173,7 @@ typedef enum PaWasapiJackPortConnection
|
|||
PaWasapiJackPortConnection;
|
||||
|
||||
|
||||
/* Thread priority */
|
||||
/* Thread priority. */
|
||||
typedef enum PaWasapiThreadPriority
|
||||
{
|
||||
eThreadPriorityNone = 0,
|
||||
|
@ -202,6 +202,46 @@ typedef struct PaWasapiJackDescription
|
|||
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
|
||||
|
||||
@version Available as of 19.6.0
|
||||
*/
|
||||
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
|
||||
|
||||
@version Available as of 19.6.0
|
||||
*/
|
||||
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
|
||||
{
|
||||
|
@ -211,7 +251,7 @@ typedef struct PaWasapiStreamInfo
|
|||
|
||||
unsigned long flags; /**< collection of PaWasapiFlags */
|
||||
|
||||
/* Support for WAVEFORMATEXTENSIBLE channel masks. If flags contains
|
||||
/** 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
|
||||
|
@ -219,7 +259,7 @@ typedef struct PaWasapiStreamInfo
|
|||
*/
|
||||
PaWinWaveFormatChannelMask channelMask;
|
||||
|
||||
/* Delivers raw data to callback obtained from GetBuffer() methods skipping
|
||||
/** 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.
|
||||
|
@ -227,7 +267,7 @@ typedef struct PaWasapiStreamInfo
|
|||
PaWasapiHostProcessorCallback hostProcessorOutput;
|
||||
PaWasapiHostProcessorCallback hostProcessorInput;
|
||||
|
||||
/* Specifies thread priority explicitly. Will be used only if paWinWasapiThreadPriority flag
|
||||
/** 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)
|
||||
|
@ -235,6 +275,18 @@ typedef struct PaWasapiStreamInfo
|
|||
to setup thread priority.
|
||||
*/
|
||||
PaWasapiThreadPriority threadPriority;
|
||||
|
||||
/** Stream category.
|
||||
@see PaWasapiStreamCategory
|
||||
@version Available as of 19.6.0
|
||||
*/
|
||||
PaWasapiStreamCategory streamCategory;
|
||||
|
||||
/** Stream option.
|
||||
@see PaWasapiStreamOption
|
||||
@version Available as of 19.6.0
|
||||
*/
|
||||
PaWasapiStreamOption streamOption;
|
||||
}
|
||||
PaWasapiStreamInfo;
|
||||
|
||||
|
@ -303,7 +355,7 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
|
|||
|
||||
/** 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.
|
||||
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
|
||||
|
@ -314,9 +366,9 @@ 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.
|
||||
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.
|
||||
|
@ -347,7 +399,7 @@ PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJ
|
|||
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.
|
||||
lower than 20 ms.
|
||||
|
||||
2) Poll-Driven:
|
||||
Polling is another 2-nd method to operate with WASAPI. It is less efficient than Event-Driven
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
#ifndef PA_WIN_WDMKS_H
|
||||
#define PA_WIN_WDMKS_H
|
||||
/*
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* WDM/KS 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 WDM Kernel Streaming-specific PortAudio API extension header file.
|
||||
*/
|
||||
|
||||
|
||||
#include "portaudio.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** Flags to indicate valid fields in PaWinWDMKSInfo.
|
||||
@see PaWinWDMKSInfo
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
typedef enum PaWinWDMKSFlags
|
||||
{
|
||||
/** Makes WDMKS use the supplied latency figures instead of relying on the frame size reported
|
||||
by the WaveCyclic device. Use at own risk!
|
||||
*/
|
||||
paWinWDMKSOverrideFramesize = (1 << 0),
|
||||
|
||||
/** Makes WDMKS (output stream) use the given channelMask instead of the default.
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
paWinWDMKSUseGivenChannelMask = (1 << 1),
|
||||
|
||||
} PaWinWDMKSFlags;
|
||||
|
||||
typedef struct PaWinWDMKSInfo{
|
||||
unsigned long size; /**< sizeof(PaWinWDMKSInfo) */
|
||||
PaHostApiTypeId hostApiType; /**< paWDMKS */
|
||||
unsigned long version; /**< 1 */
|
||||
|
||||
/** Flags indicate which fields are valid.
|
||||
@see PaWinWDMKSFlags
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
unsigned long flags;
|
||||
|
||||
/** The number of packets to use for WaveCyclic devices, range is [2, 8]. Set to zero for default value of 2. */
|
||||
unsigned noOfPackets;
|
||||
|
||||
/** If paWinWDMKSUseGivenChannelMask bit is set in flags, use this as channelMask instead of default.
|
||||
@see PaWinWDMKSFlags
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
unsigned channelMask;
|
||||
} PaWinWDMKSInfo;
|
||||
|
||||
typedef enum PaWDMKSType
|
||||
{
|
||||
Type_kNotUsed,
|
||||
Type_kWaveCyclic,
|
||||
Type_kWaveRT,
|
||||
Type_kCnt,
|
||||
} PaWDMKSType;
|
||||
|
||||
typedef enum PaWDMKSSubType
|
||||
{
|
||||
SubType_kUnknown,
|
||||
SubType_kNotification,
|
||||
SubType_kPolled,
|
||||
SubType_kCnt,
|
||||
} PaWDMKSSubType;
|
||||
|
||||
typedef struct PaWinWDMKSDeviceInfo {
|
||||
wchar_t filterPath[MAX_PATH]; /**< KS filter path in Unicode! */
|
||||
wchar_t topologyPath[MAX_PATH]; /**< Topology filter path in Unicode! */
|
||||
PaWDMKSType streamingType;
|
||||
GUID deviceProductGuid; /**< The product GUID of the device (if supported) */
|
||||
} PaWinWDMKSDeviceInfo;
|
||||
|
||||
typedef struct PaWDMKSDirectionSpecificStreamInfo
|
||||
{
|
||||
PaDeviceIndex device;
|
||||
unsigned channels; /**< No of channels the device is opened with */
|
||||
unsigned framesPerHostBuffer; /**< No of frames of the device buffer */
|
||||
int endpointPinId; /**< Endpoint pin ID (on topology filter if topologyName is not empty) */
|
||||
int muxNodeId; /**< Only valid for input */
|
||||
PaWDMKSSubType streamingSubType; /**< Not known until device is opened for streaming */
|
||||
} PaWDMKSDirectionSpecificStreamInfo;
|
||||
|
||||
typedef struct PaWDMKSSpecificStreamInfo {
|
||||
PaWDMKSDirectionSpecificStreamInfo input;
|
||||
PaWDMKSDirectionSpecificStreamInfo output;
|
||||
} PaWDMKSSpecificStreamInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* PA_WIN_DS_H */
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_WIN_WMME_H
|
||||
#define PA_WIN_WMME_H
|
||||
/*
|
||||
* $Id: pa_win_wmme.h 1592 2011-02-04 10:41:58Z rossb $
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* MME specific extensions
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PORTAUDIO_H
|
||||
#define PORTAUDIO_H
|
||||
/*
|
||||
* $Id: portaudio.h 1745 2011-08-25 17:44:01Z rossb $
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* PortAudio API Header File
|
||||
* Latest version available at: http://www.portaudio.com/
|
||||
|
@ -50,18 +50,69 @@ extern "C"
|
|||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/** Retrieve the release number of the currently running PortAudio build,
|
||||
eg 1900.
|
||||
/** Retrieve the release number of the currently running PortAudio build.
|
||||
For example, for version "19.5.1" this will return 0x00130501.
|
||||
|
||||
@see paMakeVersionNumber
|
||||
*/
|
||||
int Pa_GetVersion( void );
|
||||
|
||||
|
||||
/** Retrieve a textual description of the current PortAudio build,
|
||||
eg "PortAudio V19-devel 13 October 2002".
|
||||
e.g. "PortAudio V19.5.0-devel, revision 1952M".
|
||||
The format of the text may change in the future. Do not try to parse the
|
||||
returned string.
|
||||
|
||||
@deprecated As of 19.5.0, use Pa_GetVersionInfo()->versionText instead.
|
||||
*/
|
||||
const char* Pa_GetVersionText( void );
|
||||
|
||||
/**
|
||||
Generate a packed integer version number in the same format used
|
||||
by Pa_GetVersion(). Use this to compare a specified version number with
|
||||
the currently running version. For example:
|
||||
|
||||
@code
|
||||
if( Pa_GetVersion() < paMakeVersionNumber(19,5,1) ) {}
|
||||
@endcode
|
||||
|
||||
@see Pa_GetVersion, Pa_GetVersionInfo
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
#define paMakeVersionNumber(major, minor, subminor) \
|
||||
(((major)&0xFF)<<16 | ((minor)&0xFF)<<8 | ((subminor)&0xFF))
|
||||
|
||||
|
||||
/**
|
||||
A structure containing PortAudio API version information.
|
||||
@see Pa_GetVersionInfo, paMakeVersionNumber
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
typedef struct PaVersionInfo {
|
||||
int versionMajor;
|
||||
int versionMinor;
|
||||
int versionSubMinor;
|
||||
/**
|
||||
This is currently the Git revision hash but may change in the future.
|
||||
The versionControlRevision is updated by running a script before compiling the library.
|
||||
If the update does not occur, this value may refer to an earlier revision.
|
||||
*/
|
||||
const char *versionControlRevision;
|
||||
/** Version as a string, for example "PortAudio V19.5.0-devel, revision 1952M" */
|
||||
const char *versionText;
|
||||
} PaVersionInfo;
|
||||
|
||||
/** Retrieve version information for the currently running PortAudio build.
|
||||
@return A pointer to an immutable PaVersionInfo structure.
|
||||
|
||||
@note This function can be called at any time. It does not require PortAudio
|
||||
to be initialized. The structure pointed to is statically allocated. Do not
|
||||
attempt to free it or modify it.
|
||||
|
||||
@see PaVersionInfo, paMakeVersionNumber
|
||||
@version Available as of 19.5.0.
|
||||
*/
|
||||
const PaVersionInfo* Pa_GetVersionInfo();
|
||||
|
||||
|
||||
/** Error codes returned by PortAudio functions.
|
||||
Note that with the exception of paNoError, all PaErrorCodes are negative.
|
||||
|
@ -900,7 +951,7 @@ PaError Pa_CloseStream( PaStream *stream );
|
|||
(ie once a call to Pa_StopStream() will not block).
|
||||
A stream will become inactive after the stream callback returns non-zero,
|
||||
or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
|
||||
output, if the stream callback returns paComplete, or Pa_StopStream is called,
|
||||
output, if the stream callback returns paComplete, or Pa_StopStream() is called,
|
||||
the stream finished callback will not be called until all generated sample data
|
||||
has been played.
|
||||
|
||||
|
@ -1021,7 +1072,7 @@ typedef struct PaStreamInfo
|
|||
/** Retrieve a pointer to a PaStreamInfo structure containing information
|
||||
about the specified stream.
|
||||
@return A pointer to an immutable PaStreamInfo structure. If the stream
|
||||
parameter invalid, or an error is encountered, the function returns NULL.
|
||||
parameter is invalid, or an error is encountered, the function returns NULL.
|
||||
|
||||
@param stream A pointer to an open stream previously created with Pa_OpenStream.
|
||||
|
||||
|
@ -1098,7 +1149,7 @@ PaError Pa_ReadStream( PaStream* stream,
|
|||
|
||||
|
||||
/** Write samples to an output stream. This function doesn't return until the
|
||||
entire buffer has been consumed - this may involve waiting for the operating
|
||||
entire buffer has been written - this may involve waiting for the operating
|
||||
system to consume the data.
|
||||
|
||||
@param stream A pointer to an open stream previously created with Pa_OpenStream.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_allocation.c 1097 2006-08-26 08:27:53Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library allocation group implementation
|
||||
* memory allocation group for tracking allocation groups
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_ALLOCATION_H
|
||||
#define PA_ALLOCATION_H
|
||||
/*
|
||||
* $Id: pa_allocation.h 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library allocation context header
|
||||
* memory allocation context for tracking allocation groups
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_converters.c 1748 2011-09-01 22:08:32Z philburk $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library sample conversion mechanism
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_CONVERTERS_H
|
||||
#define PA_CONVERTERS_H
|
||||
/*
|
||||
* $Id: pa_converters.h 1097 2006-08-26 08:27:53Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library sample conversion mechanism
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_cpuload.c 1577 2011-02-01 13:03:45Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library CPU Load measurement functions
|
||||
* Portable CPU load measurement facility.
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_CPULOAD_H
|
||||
#define PA_CPULOAD_H
|
||||
/*
|
||||
* $Id: pa_cpuload.h 1097 2006-08-26 08:27:53Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library CPU Load measurement functions
|
||||
* Portable CPU load measurement facility.
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_dither.c 1418 2009-10-12 21:00:53Z philburk $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library triangular dither generator
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_DITHER_H
|
||||
#define PA_DITHER_H
|
||||
/*
|
||||
* $Id: pa_dither.h 1418 2009-10-12 21:00:53Z philburk $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library triangular dither generator
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_ENDIANNESS_H
|
||||
#define PA_ENDIANNESS_H
|
||||
/*
|
||||
* $Id: pa_endianness.h 1324 2008-01-27 02:03:30Z bjornroche $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library current platform endianness macros
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_front.c 1730 2011-08-18 03:43:51Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library Multi-Host API front end
|
||||
* Validate function parameters and manage multiple host APIs.
|
||||
*
|
||||
|
@ -27,26 +27,26 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* The text above constitutes the entire PortAudio license; however,
|
||||
* 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
|
||||
* 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 common_src
|
||||
|
||||
@brief Implements PortAudio API functions defined in portaudio.h, checks
|
||||
@brief Implements PortAudio API functions defined in portaudio.h, checks
|
||||
some errors, delegates platform-specific behavior to host API implementations.
|
||||
|
||||
Implements the functions defined in the PortAudio API (portaudio.h),
|
||||
validates some parameters and checks for state inconsistencies before
|
||||
forwarding API requests to specific Host API implementations (via the
|
||||
interface declared in pa_hostapi.h), and Streams (via the interface
|
||||
|
||||
Implements the functions defined in the PortAudio API (portaudio.h),
|
||||
validates some parameters and checks for state inconsistencies before
|
||||
forwarding API requests to specific Host API implementations (via the
|
||||
interface declared in pa_hostapi.h), and Streams (via the interface
|
||||
declared in pa_stream.h).
|
||||
|
||||
This file manages initialization and termination of Host API
|
||||
|
@ -65,6 +65,7 @@
|
|||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h> /* needed for strtol() */
|
||||
#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
|
||||
|
||||
#include "portaudio.h"
|
||||
|
@ -76,25 +77,63 @@
|
|||
#include "pa_trace.h" /* still usefull?*/
|
||||
#include "pa_debugprint.h"
|
||||
|
||||
#ifndef PA_GIT_REVISION
|
||||
#include "pa_gitrevision.h"
|
||||
#endif
|
||||
|
||||
#define PA_VERSION_ 1899
|
||||
#define PA_VERSION_TEXT_ "PortAudio V19-devel (built " __DATE__ " " __TIME__ ")"
|
||||
/**
|
||||
* This is incremented if we make incompatible API changes.
|
||||
* This version scheme is based loosely on http://semver.org/
|
||||
*/
|
||||
#define paVersionMajor 19
|
||||
|
||||
/**
|
||||
* This is incremented when we add functionality in a backwards-compatible manner.
|
||||
* Or it is set to zero when paVersionMajor is incremented.
|
||||
*/
|
||||
#define paVersionMinor 6
|
||||
|
||||
/**
|
||||
* This is incremented when we make backwards-compatible bug fixes.
|
||||
* Or it is set to zero when paVersionMinor changes.
|
||||
*/
|
||||
#define paVersionSubMinor 0
|
||||
|
||||
/**
|
||||
* This is a combination of paVersionMajor, paVersionMinor and paVersionSubMinor.
|
||||
* It will always increase so that version numbers can be compared as integers to
|
||||
* see which is later.
|
||||
*/
|
||||
#define paVersion paMakeVersionNumber(paVersionMajor, paVersionMinor, paVersionSubMinor)
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
|
||||
#define PA_VERSION_STRING_ TOSTRING(paVersionMajor) "." TOSTRING(paVersionMinor) "." TOSTRING(paVersionSubMinor)
|
||||
#define PA_VERSION_TEXT_ "PortAudio V" PA_VERSION_STRING_ "-devel, revision " TOSTRING(PA_GIT_REVISION)
|
||||
|
||||
int Pa_GetVersion( void )
|
||||
{
|
||||
return PA_VERSION_;
|
||||
return paVersion;
|
||||
}
|
||||
|
||||
|
||||
const char* Pa_GetVersionText( void )
|
||||
{
|
||||
return PA_VERSION_TEXT_;
|
||||
}
|
||||
|
||||
static PaVersionInfo versionInfo_ = {
|
||||
/*.versionMajor =*/ paVersionMajor,
|
||||
/*.versionMinor =*/ paVersionMinor,
|
||||
/*.versionSubMinor =*/ paVersionSubMinor,
|
||||
/*.versionControlRevision =*/ TOSTRING(PA_GIT_REVISION),
|
||||
/*.versionText =*/ PA_VERSION_TEXT_
|
||||
};
|
||||
|
||||
const PaVersionInfo* Pa_GetVersionInfo()
|
||||
{
|
||||
return &versionInfo_;
|
||||
}
|
||||
|
||||
#define PA_LAST_HOST_ERROR_TEXT_LENGTH_ 1024
|
||||
|
||||
|
@ -170,7 +209,7 @@ static PaError InitializeHostApis( void )
|
|||
if( !hostApis_ )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error;
|
||||
goto error;
|
||||
}
|
||||
|
||||
hostApisCount_ = 0;
|
||||
|
@ -196,11 +235,11 @@ static PaError InitializeHostApis( void )
|
|||
assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
|
||||
assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
|
||||
|
||||
/* the first successfully initialized host API with a default input *or*
|
||||
/* the first successfully initialized host API with a default input *or*
|
||||
output device is used as the default host API.
|
||||
*/
|
||||
if( (defaultHostApiIndex_ == -1) &&
|
||||
( hostApi->info.defaultInputDevice != paNoDevice
|
||||
( hostApi->info.defaultInputDevice != paNoDevice
|
||||
|| hostApi->info.defaultOutputDevice != paNoDevice ) )
|
||||
{
|
||||
defaultHostApiIndex_ = hostApisCount_;
|
||||
|
@ -238,7 +277,7 @@ error:
|
|||
<device> belongs and returns it. if <hostSpecificDeviceIndex> is
|
||||
non-null, the host specific device index is returned in it.
|
||||
returns -1 if <device> is out of range.
|
||||
|
||||
|
||||
*/
|
||||
static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
|
||||
{
|
||||
|
@ -328,7 +367,7 @@ PaError Pa_Initialize( void )
|
|||
{
|
||||
PA_VALIDATE_TYPE_SIZES;
|
||||
PA_VALIDATE_ENDIANNESS;
|
||||
|
||||
|
||||
PaUtil_InitializeClock();
|
||||
PaUtil_ResetTraceMessages();
|
||||
|
||||
|
@ -351,7 +390,8 @@ PaError Pa_Terminate( void )
|
|||
|
||||
if( PA_IS_INITIALISED_ )
|
||||
{
|
||||
if( --initializationCount_ == 0 )
|
||||
// leave initializationCount_>0 so that Pa_CloseStream() can execute
|
||||
if( initializationCount_ == 1 )
|
||||
{
|
||||
CloseOpenStreams();
|
||||
|
||||
|
@ -359,6 +399,7 @@ PaError Pa_Terminate( void )
|
|||
|
||||
PaUtil_DumpTraceMessages();
|
||||
}
|
||||
--initializationCount_;
|
||||
result = paNoError;
|
||||
}
|
||||
else
|
||||
|
@ -415,11 +456,11 @@ const char *Pa_GetErrorText( PaError errorCode )
|
|||
case paCanNotWriteToAnInputOnlyStream: result = "Can't write to an input only stream"; break;
|
||||
case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break;
|
||||
case paBadBufferPtr: result = "Bad buffer pointer"; break;
|
||||
default:
|
||||
default:
|
||||
if( errorCode > 0 )
|
||||
result = "Invalid error code (value greater than zero)";
|
||||
result = "Invalid error code (value greater than zero)";
|
||||
else
|
||||
result = "Invalid error code";
|
||||
result = "Invalid error code";
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
|
@ -430,7 +471,7 @@ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
|
|||
{
|
||||
PaHostApiIndex result;
|
||||
int i;
|
||||
|
||||
|
||||
PA_LOGAPI_ENTER_PARAMS( "Pa_HostApiTypeIdToHostApiIndex" );
|
||||
PA_LOGAPI(("\tPaHostApiTypeId type: %d\n", type ));
|
||||
|
||||
|
@ -441,14 +482,14 @@ PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
|
|||
else
|
||||
{
|
||||
result = paHostApiNotFound;
|
||||
|
||||
|
||||
for( i=0; i < hostApisCount_; ++i )
|
||||
{
|
||||
if( hostApis_[i]->info.type == type )
|
||||
{
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,7 +504,7 @@ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **ho
|
|||
{
|
||||
PaError result;
|
||||
int i;
|
||||
|
||||
|
||||
if( !PA_IS_INITIALISED_ )
|
||||
{
|
||||
result = paNotInitialized;
|
||||
|
@ -471,7 +512,7 @@ PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **ho
|
|||
else
|
||||
{
|
||||
result = paHostApiNotFound;
|
||||
|
||||
|
||||
for( i=0; i < hostApisCount_; ++i )
|
||||
{
|
||||
if( hostApis_[i]->info.type == type )
|
||||
|
@ -492,7 +533,7 @@ PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
|
|||
{
|
||||
PaError result;
|
||||
PaDeviceIndex x;
|
||||
|
||||
|
||||
x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
|
||||
|
||||
if( x < 0 || x >= hostApi->info.deviceCount )
|
||||
|
@ -577,7 +618,7 @@ const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
|
|||
else if( hostApi < 0 || hostApi >= hostApisCount_ )
|
||||
{
|
||||
info = NULL;
|
||||
|
||||
|
||||
PA_LOGAPI(("Pa_GetHostApiInfo returned:\n" ));
|
||||
PA_LOGAPI(("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n" ));
|
||||
|
||||
|
@ -686,7 +727,7 @@ PaDeviceIndex Pa_GetDefaultOutputDevice( void )
|
|||
{
|
||||
PaHostApiIndex hostApi;
|
||||
PaDeviceIndex result;
|
||||
|
||||
|
||||
PA_LOGAPI_ENTER( "Pa_GetDefaultOutputDevice" );
|
||||
|
||||
hostApi = Pa_GetDefaultHostApi();
|
||||
|
@ -770,7 +811,7 @@ static int SampleFormatIsValid( PaSampleFormat format )
|
|||
ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream()
|
||||
conform to the expected values as described below. This function is
|
||||
also designed to be used with the proposed Pa_IsFormatSupported() function.
|
||||
|
||||
|
||||
There are basically two types of validation that could be performed:
|
||||
Generic conformance validation, and device capability mismatch
|
||||
validation. This function performs only generic conformance validation.
|
||||
|
@ -779,21 +820,21 @@ static int SampleFormatIsValid( PaSampleFormat format )
|
|||
combinations of parameters - for example, even if the sampleRate
|
||||
seems ok, it might not be for a duplex stream - we have no way of
|
||||
checking this in an API-neutral way, so we don't try.
|
||||
|
||||
|
||||
On success the function returns PaNoError and fills in hostApi,
|
||||
hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure
|
||||
the function returns an error code indicating the first encountered
|
||||
parameter error.
|
||||
|
||||
|
||||
|
||||
|
||||
If ValidateOpenStreamParameters() returns paNoError, the following
|
||||
assertions are guaranteed to be true.
|
||||
|
||||
|
||||
- at least one of inputParameters & outputParmeters is valid (not NULL)
|
||||
|
||||
- if inputParameters & outputParameters are both valid, that
|
||||
inputParameters->device & outputParameters->device both use the same host api
|
||||
|
||||
|
||||
PaDeviceIndex inputParameters->device
|
||||
- is within range (0 to Pa_GetDeviceCount-1) Or:
|
||||
- is paUseHostApiSpecificDeviceSpecification and
|
||||
|
@ -803,30 +844,30 @@ static int SampleFormatIsValid( PaSampleFormat format )
|
|||
int inputParameters->channelCount
|
||||
- if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
|
||||
- upper bound is NOT validated against device capabilities
|
||||
|
||||
|
||||
PaSampleFormat inputParameters->sampleFormat
|
||||
- is one of the sample formats defined in portaudio.h
|
||||
|
||||
void *inputParameters->hostApiSpecificStreamInfo
|
||||
- if supplied its hostApi field matches the input device's host Api
|
||||
|
||||
|
||||
PaDeviceIndex outputParmeters->device
|
||||
- is within range (0 to Pa_GetDeviceCount-1)
|
||||
|
||||
|
||||
int outputParmeters->channelCount
|
||||
- if inputDevice is valid, channelCount is > 0
|
||||
- upper bound is NOT validated against device capabilities
|
||||
|
||||
|
||||
PaSampleFormat outputParmeters->sampleFormat
|
||||
- is one of the sample formats defined in portaudio.h
|
||||
|
||||
|
||||
void *outputParmeters->hostApiSpecificStreamInfo
|
||||
- if supplied its hostApi field matches the output device's host Api
|
||||
|
||||
|
||||
double sampleRate
|
||||
- is not an 'absurd' rate (less than 1000. or greater than 200000.)
|
||||
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
|
||||
- sampleRate is NOT validated against device capabilities
|
||||
|
||||
|
||||
PaStreamFlags streamFlags
|
||||
- unused platform neutral flags are zero
|
||||
- paNeverDropInput is only used for full-duplex callback streams with
|
||||
|
@ -953,7 +994,7 @@ static PaError ValidateOpenStreamParameters(
|
|||
!= (*hostApi)->info.type )
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( (inputParameters != NULL) && (outputParameters != NULL) )
|
||||
{
|
||||
|
@ -962,10 +1003,10 @@ static PaError ValidateOpenStreamParameters(
|
|||
return paBadIODeviceCombination;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Check for absurd sample rates. */
|
||||
if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
|
||||
if( (sampleRate < 1000.0) || (sampleRate > 384000.0) )
|
||||
return paInvalidSampleRate;
|
||||
|
||||
if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
|
||||
|
@ -985,7 +1026,7 @@ static PaError ValidateOpenStreamParameters(
|
|||
if( framesPerBuffer != paFramesPerBufferUnspecified )
|
||||
return paInvalidFlag;
|
||||
}
|
||||
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1066,7 @@ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
|
|||
PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
|
||||
PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
|
||||
}
|
||||
|
||||
|
||||
PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
|
||||
#endif
|
||||
|
||||
|
@ -1048,7 +1089,7 @@ PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
|
|||
PA_LOGAPI_EXIT_PAERROR( "Pa_IsFormatSupported", result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( inputParameters )
|
||||
{
|
||||
|
@ -1135,7 +1176,7 @@ PaError Pa_OpenStream( PaStream** stream,
|
|||
PA_LOGAPI(("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency ));
|
||||
PA_LOGAPI(("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo ));
|
||||
}
|
||||
|
||||
|
||||
PA_LOGAPI(("\tdouble sampleRate: %g\n", sampleRate ));
|
||||
PA_LOGAPI(("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer ));
|
||||
PA_LOGAPI(("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags ));
|
||||
|
@ -1182,7 +1223,7 @@ PaError Pa_OpenStream( PaStream** stream,
|
|||
PA_LOGAPI(("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) ));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if( inputParameters )
|
||||
{
|
||||
|
@ -1256,8 +1297,8 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
|
|||
{
|
||||
hostApiInputParameters.device = Pa_GetDefaultInputDevice();
|
||||
if( hostApiInputParameters.device == paNoDevice )
|
||||
return paDeviceUnavailable;
|
||||
|
||||
return paDeviceUnavailable;
|
||||
|
||||
hostApiInputParameters.channelCount = inputChannelCount;
|
||||
hostApiInputParameters.sampleFormat = sampleFormat;
|
||||
/* defaultHighInputLatency is used below instead of
|
||||
|
@ -1265,7 +1306,7 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
|
|||
stream to work reliably than it is for it to work with the lowest
|
||||
latency.
|
||||
*/
|
||||
hostApiInputParameters.suggestedLatency =
|
||||
hostApiInputParameters.suggestedLatency =
|
||||
Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
|
||||
hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
|
||||
hostApiInputParametersPtr = &hostApiInputParameters;
|
||||
|
@ -1279,7 +1320,7 @@ PaError Pa_OpenDefaultStream( PaStream** stream,
|
|||
{
|
||||
hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
|
||||
if( hostApiOutputParameters.device == paNoDevice )
|
||||
return paDeviceUnavailable;
|
||||
return paDeviceUnavailable;
|
||||
|
||||
hostApiOutputParameters.channelCount = outputChannelCount;
|
||||
hostApiOutputParameters.sampleFormat = sampleFormat;
|
||||
|
@ -1663,7 +1704,7 @@ PaError Pa_WriteStream( PaStream* stream,
|
|||
else if( result == 1 )
|
||||
{
|
||||
result = paStreamIsStopped;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#define PA_GIT_REVISION 396fe4b6699ae929d3a685b3ef8a7e97396139a4
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_HOSTAPI_H
|
||||
#define PA_HOSTAPI_H
|
||||
/*
|
||||
* $Id: pa_hostapi.h 1740 2011-08-25 07:17:48Z philburk $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* host api representation
|
||||
*
|
||||
|
@ -264,7 +264,7 @@ typedef struct PaUtilHostApiRepresentation {
|
|||
- if supplied its hostApi field matches the output device's host Api
|
||||
|
||||
double sampleRate
|
||||
- is not an 'absurd' rate (less than 1000. or greater than 200000.)
|
||||
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
|
||||
- sampleRate is NOT validated against device capabilities
|
||||
|
||||
PaStreamFlags streamFlags
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_process.c 1706 2011-07-21 18:44:58Z philburk $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* streamCallback <-> host buffer processing adapter
|
||||
*
|
||||
|
@ -238,7 +238,7 @@ PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
|
|||
bp->inputConverter =
|
||||
PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags );
|
||||
|
||||
bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );
|
||||
bp->inputZeroer = PaUtil_SelectZeroer( userInputSampleFormat );
|
||||
|
||||
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
|
||||
|
||||
|
@ -743,8 +743,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
|||
destSampleStrideSamples = bp->inputChannelCount;
|
||||
destChannelStrideBytes = bp->bytesPerUserInputSample;
|
||||
|
||||
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
|
||||
if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved && bp->hostInputChannels[0][0].data)
|
||||
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved,
|
||||
* or if num channels differs between the host (set in stride) and the user (eg with some Alsa hw:) */
|
||||
if( bp->userInputSampleFormatIsEqualToHost && bp->hostInputIsInterleaved
|
||||
&& bp->hostInputChannels[0][0].data && bp->inputChannelCount == hostInputChannels[0].stride )
|
||||
{
|
||||
userInput = hostInputChannels[0].data;
|
||||
destBytePtr = (unsigned char *)hostInputChannels[0].data;
|
||||
|
@ -832,8 +834,10 @@ static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
|
|||
{
|
||||
if( bp->userOutputIsInterleaved )
|
||||
{
|
||||
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved */
|
||||
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved )
|
||||
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved,
|
||||
* or if num channels differs between the host (set in stride) and the user (eg with some Alsa hw:) */
|
||||
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved
|
||||
&& bp->outputChannelCount == hostOutputChannels[0].stride )
|
||||
{
|
||||
userOutput = hostOutputChannels[0].data;
|
||||
skipOutputConvert = 1;
|
||||
|
@ -1683,9 +1687,9 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
|
|||
hostInputChannels[i].stride,
|
||||
framesToCopy, &bp->ditherGenerator );
|
||||
|
||||
destBytePtr += destChannelStrideBytes; /* skip to next source channel */
|
||||
destBytePtr += destChannelStrideBytes; /* skip to next dest channel */
|
||||
|
||||
/* advance dest ptr for next iteration */
|
||||
/* advance source ptr for next iteration */
|
||||
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
|
||||
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
|
||||
}
|
||||
|
@ -1715,7 +1719,7 @@ unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
|
|||
destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
|
||||
nonInterleavedDestPtrs[i] = destBytePtr;
|
||||
|
||||
/* advance dest ptr for next iteration */
|
||||
/* advance source ptr for next iteration */
|
||||
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
|
||||
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_PROCESS_H
|
||||
#define PA_PROCESS_H
|
||||
/*
|
||||
* $Id: pa_process.h 1668 2011-05-02 17:07:11Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library callback buffer processing adapters
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_ringbuffer.c 1738 2011-08-18 11:47:28Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* Ring Buffer utility.
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_RINGBUFFER_H
|
||||
#define PA_RINGBUFFER_H
|
||||
/*
|
||||
* $Id: pa_ringbuffer.h 1734 2011-08-18 11:19:36Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* Ring Buffer utility.
|
||||
*
|
||||
|
@ -65,6 +65,9 @@
|
|||
The memory area used to store the buffer elements must be allocated by
|
||||
the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
|
||||
the use of the ring buffer.
|
||||
|
||||
@note The ring buffer functions are not normally exposed in the PortAudio libraries.
|
||||
If you want to call them then you will need to add pa_ringbuffer.c to your application source code.
|
||||
*/
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_stream.c 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* stream interface
|
||||
*
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_STREAM_H
|
||||
#define PA_STREAM_H
|
||||
/*
|
||||
* $Id: pa_stream.h 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* stream interface
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_trace.c 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library Trace Facility
|
||||
* Store trace information in real-time for later printing.
|
||||
*
|
||||
|
@ -46,12 +46,16 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "pa_trace.h"
|
||||
#include "pa_util.h"
|
||||
#include "pa_debugprint.h"
|
||||
|
||||
#if PA_TRACE_REALTIME_EVENTS
|
||||
|
||||
static char *traceTextArray[PA_MAX_TRACE_RECORDS];
|
||||
static char const *traceTextArray[PA_MAX_TRACE_RECORDS];
|
||||
static int traceIntArray[PA_MAX_TRACE_RECORDS];
|
||||
static int traceIndex = 0;
|
||||
static int traceBlock = 0;
|
||||
|
@ -94,4 +98,141 @@ void PaUtil_AddTraceMessage( const char *msg, int data )
|
|||
}
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* High performance log alternative */
|
||||
/************************************************************************/
|
||||
|
||||
typedef unsigned long long PaUint64;
|
||||
|
||||
typedef struct __PaHighPerformanceLog
|
||||
{
|
||||
unsigned magik;
|
||||
int writePtr;
|
||||
int readPtr;
|
||||
int size;
|
||||
double refTime;
|
||||
char* data;
|
||||
} PaHighPerformanceLog;
|
||||
|
||||
static const unsigned kMagik = 0xcafebabe;
|
||||
|
||||
#define USEC_PER_SEC (1000000ULL)
|
||||
|
||||
int PaUtil_InitializeHighSpeedLog( LogHandle* phLog, unsigned maxSizeInBytes )
|
||||
{
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)PaUtil_AllocateMemory(sizeof(PaHighPerformanceLog));
|
||||
if (pLog == 0)
|
||||
{
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
assert(phLog != 0);
|
||||
*phLog = pLog;
|
||||
|
||||
pLog->data = (char*)PaUtil_AllocateMemory(maxSizeInBytes);
|
||||
if (pLog->data == 0)
|
||||
{
|
||||
PaUtil_FreeMemory(pLog);
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
pLog->magik = kMagik;
|
||||
pLog->size = maxSizeInBytes;
|
||||
pLog->refTime = PaUtil_GetTime();
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
void PaUtil_ResetHighSpeedLogTimeRef( LogHandle hLog )
|
||||
{
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
assert(pLog->magik == kMagik);
|
||||
pLog->refTime = PaUtil_GetTime();
|
||||
}
|
||||
|
||||
typedef struct __PaLogEntryHeader
|
||||
{
|
||||
int size;
|
||||
double timeStamp;
|
||||
} PaLogEntryHeader;
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define _vsnprintf vsnprintf
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
|
||||
int PaUtil_AddHighSpeedLogMessage( LogHandle hLog, const char* fmt, ... )
|
||||
{
|
||||
va_list l;
|
||||
int n = 0;
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
if (pLog != 0)
|
||||
{
|
||||
PaLogEntryHeader* pHeader;
|
||||
char* p;
|
||||
int maxN;
|
||||
assert(pLog->magik == kMagik);
|
||||
pHeader = (PaLogEntryHeader*)( pLog->data + pLog->writePtr );
|
||||
p = (char*)( pHeader + 1 );
|
||||
maxN = pLog->size - pLog->writePtr - 2 * sizeof(PaLogEntryHeader);
|
||||
|
||||
pHeader->timeStamp = PaUtil_GetTime() - pLog->refTime;
|
||||
if (maxN > 0)
|
||||
{
|
||||
if (maxN > 32)
|
||||
{
|
||||
va_start(l, fmt);
|
||||
n = _vsnprintf(p, min(1024, maxN), fmt, l);
|
||||
va_end(l);
|
||||
}
|
||||
else {
|
||||
n = sprintf(p, "End of log...");
|
||||
}
|
||||
n = ((n + sizeof(unsigned)) & ~(sizeof(unsigned)-1)) + sizeof(PaLogEntryHeader);
|
||||
pHeader->size = n;
|
||||
#if 0
|
||||
PaUtil_DebugPrint("%05u.%03u: %s\n", pHeader->timeStamp/1000, pHeader->timeStamp%1000, p);
|
||||
#endif
|
||||
pLog->writePtr += n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void PaUtil_DumpHighSpeedLog( LogHandle hLog, const char* fileName )
|
||||
{
|
||||
FILE* f = (fileName != NULL) ? fopen(fileName, "w") : stdout;
|
||||
unsigned localWritePtr;
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
assert(pLog->magik == kMagik);
|
||||
localWritePtr = pLog->writePtr;
|
||||
while (pLog->readPtr != localWritePtr)
|
||||
{
|
||||
const PaLogEntryHeader* pHeader = (const PaLogEntryHeader*)( pLog->data + pLog->readPtr );
|
||||
const char* p = (const char*)( pHeader + 1 );
|
||||
const PaUint64 ts = (const PaUint64)( pHeader->timeStamp * USEC_PER_SEC );
|
||||
assert(pHeader->size < (1024+sizeof(unsigned)+sizeof(PaLogEntryHeader)));
|
||||
fprintf(f, "%05u.%03u: %s\n", (unsigned)(ts/1000), (unsigned)(ts%1000), p);
|
||||
pLog->readPtr += pHeader->size;
|
||||
}
|
||||
if (f != stdout)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void PaUtil_DiscardHighSpeedLog( LogHandle hLog )
|
||||
{
|
||||
PaHighPerformanceLog* pLog = (PaHighPerformanceLog*)hLog;
|
||||
assert(pLog->magik == kMagik);
|
||||
PaUtil_FreeMemory(pLog->data);
|
||||
PaUtil_FreeMemory(pLog);
|
||||
}
|
||||
|
||||
#else
|
||||
/* This stub was added so that this file will generate a symbol.
|
||||
* Otherwise linker/archiver programs will complain.
|
||||
*/
|
||||
int PaUtil_TraceStubToSatisfyLinker(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* TRACE_REALTIME_EVENTS */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_TRACE_H
|
||||
#define PA_TRACE_H
|
||||
/*
|
||||
* $Id: pa_trace.h 1339 2008-02-15 07:50:33Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library Trace Facility
|
||||
* Store trace information in real-time for later printing.
|
||||
*
|
||||
|
@ -84,13 +84,29 @@ extern "C"
|
|||
void PaUtil_ResetTraceMessages();
|
||||
void PaUtil_AddTraceMessage( const char *msg, int data );
|
||||
void PaUtil_DumpTraceMessages();
|
||||
|
||||
|
||||
/* Alternative interface */
|
||||
|
||||
typedef void* LogHandle;
|
||||
|
||||
int PaUtil_InitializeHighSpeedLog(LogHandle* phLog, unsigned maxSizeInBytes);
|
||||
void PaUtil_ResetHighSpeedLogTimeRef(LogHandle hLog);
|
||||
int PaUtil_AddHighSpeedLogMessage(LogHandle hLog, const char* fmt, ...);
|
||||
void PaUtil_DumpHighSpeedLog(LogHandle hLog, const char* fileName);
|
||||
void PaUtil_DiscardHighSpeedLog(LogHandle hLog);
|
||||
|
||||
#else
|
||||
|
||||
#define PaUtil_ResetTraceMessages() /* noop */
|
||||
#define PaUtil_AddTraceMessage(msg,data) /* noop */
|
||||
#define PaUtil_DumpTraceMessages() /* noop */
|
||||
|
||||
#define PaUtil_InitializeHighSpeedLog(phLog, maxSizeInBytes) (0)
|
||||
#define PaUtil_ResetHighSpeedLogTimeRef(hLog)
|
||||
#define PaUtil_AddHighSpeedLogMessage(...) (0)
|
||||
#define PaUtil_DumpHighSpeedLog(hLog, fileName)
|
||||
#define PaUtil_DiscardHighSpeedLog(hLog)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PA_UTIL_H
|
||||
#define PA_UTIL_H
|
||||
/*
|
||||
* $Id: pa_util.h 1584 2011-02-02 18:58:17Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library implementation utilities header
|
||||
* common implementation utilities and interfaces
|
||||
*
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_asio.cpp 1778 2011-11-10 13:59:53Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library for ASIO Drivers
|
||||
*
|
||||
* Author: Stephane Letz
|
||||
|
@ -1019,6 +1019,149 @@ static ASIOSampleRate defaultSampleRateSearchOrder_[]
|
|||
192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
|
||||
|
||||
|
||||
static PaError InitPaDeviceInfoFromAsioDriver( PaAsioHostApiRepresentation *asioHostApi,
|
||||
const char *driverName, int driverIndex,
|
||||
PaDeviceInfo *deviceInfo, PaAsioDeviceInfo *asioDeviceInfo )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
|
||||
/* Due to the headless design of the ASIO API, drivers are free to write over data given to them (like M-Audio
|
||||
drivers f.i.). This is an attempt to overcome that. */
|
||||
union _tag_local {
|
||||
PaAsioDriverInfo info;
|
||||
char _padding[4096];
|
||||
} paAsioDriver;
|
||||
|
||||
asioDeviceInfo->asioChannelInfos = 0; /* we check this below to handle error cleanup */
|
||||
|
||||
result = LoadAsioDriver( asioHostApi, driverName, &paAsioDriver.info, asioHostApi->systemSpecific );
|
||||
if( result == paNoError )
|
||||
{
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", driverIndex,deviceInfo->name));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", driverIndex, paAsioDriver.info.inputChannelCount));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", driverIndex, paAsioDriver.info.outputChannelCount));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", driverIndex, paAsioDriver.info.bufferMinSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", driverIndex, paAsioDriver.info.bufferMaxSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", driverIndex, paAsioDriver.info.bufferPreferredSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", driverIndex, paAsioDriver.info.bufferGranularity));
|
||||
|
||||
deviceInfo->maxInputChannels = paAsioDriver.info.inputChannelCount;
|
||||
deviceInfo->maxOutputChannels = paAsioDriver.info.outputChannelCount;
|
||||
|
||||
deviceInfo->defaultSampleRate = 0.;
|
||||
bool foundDefaultSampleRate = false;
|
||||
for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
|
||||
{
|
||||
ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
|
||||
if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
|
||||
{
|
||||
deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
|
||||
foundDefaultSampleRate = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", driverIndex, deviceInfo->defaultSampleRate));
|
||||
|
||||
if( foundDefaultSampleRate ){
|
||||
|
||||
/* calculate default latency values from bufferPreferredSize
|
||||
for default low latency, and bufferMaxSize
|
||||
for default high latency.
|
||||
use the default sample rate to convert from samples to
|
||||
seconds. Without knowing what sample rate the user will
|
||||
use this is the best we can do.
|
||||
*/
|
||||
|
||||
double defaultLowLatency =
|
||||
paAsioDriver.info.bufferPreferredSize / deviceInfo->defaultSampleRate;
|
||||
|
||||
deviceInfo->defaultLowInputLatency = defaultLowLatency;
|
||||
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
|
||||
|
||||
double defaultHighLatency =
|
||||
paAsioDriver.info.bufferMaxSize / deviceInfo->defaultSampleRate;
|
||||
|
||||
if( defaultHighLatency < defaultLowLatency )
|
||||
defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
|
||||
|
||||
deviceInfo->defaultHighInputLatency = defaultHighLatency;
|
||||
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
|
||||
|
||||
}else{
|
||||
|
||||
deviceInfo->defaultLowInputLatency = 0.;
|
||||
deviceInfo->defaultLowOutputLatency = 0.;
|
||||
deviceInfo->defaultHighInputLatency = 0.;
|
||||
deviceInfo->defaultHighOutputLatency = 0.;
|
||||
}
|
||||
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", driverIndex, deviceInfo->defaultLowInputLatency));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", driverIndex, deviceInfo->defaultLowOutputLatency));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", driverIndex, deviceInfo->defaultHighInputLatency));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", driverIndex, deviceInfo->defaultHighOutputLatency));
|
||||
|
||||
asioDeviceInfo->minBufferSize = paAsioDriver.info.bufferMinSize;
|
||||
asioDeviceInfo->maxBufferSize = paAsioDriver.info.bufferMaxSize;
|
||||
asioDeviceInfo->preferredBufferSize = paAsioDriver.info.bufferPreferredSize;
|
||||
asioDeviceInfo->bufferGranularity = paAsioDriver.info.bufferGranularity;
|
||||
|
||||
|
||||
asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
|
||||
asioHostApi->allocations,
|
||||
sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
|
||||
+ deviceInfo->maxOutputChannels) );
|
||||
if( !asioDeviceInfo->asioChannelInfos )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error_unload;
|
||||
}
|
||||
|
||||
int a;
|
||||
|
||||
for( a=0; a < deviceInfo->maxInputChannels; ++a ){
|
||||
asioDeviceInfo->asioChannelInfos[a].channel = a;
|
||||
asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
|
||||
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
|
||||
if( asioError != ASE_OK )
|
||||
{
|
||||
result = paUnanticipatedHostError;
|
||||
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
|
||||
goto error_unload;
|
||||
}
|
||||
}
|
||||
|
||||
for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
|
||||
int b = deviceInfo->maxInputChannels + a;
|
||||
asioDeviceInfo->asioChannelInfos[b].channel = a;
|
||||
asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
|
||||
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
|
||||
if( asioError != ASE_OK )
|
||||
{
|
||||
result = paUnanticipatedHostError;
|
||||
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
|
||||
goto error_unload;
|
||||
}
|
||||
}
|
||||
|
||||
/* unload the driver */
|
||||
UnloadAsioDriver();
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
error_unload:
|
||||
UnloadAsioDriver();
|
||||
|
||||
if( asioDeviceInfo->asioChannelInfos ){
|
||||
PaUtil_GroupFreeMemory( asioHostApi->allocations, asioDeviceInfo->asioChannelInfos );
|
||||
asioDeviceInfo->asioChannelInfos = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* we look up IsDebuggerPresent at runtime incase it isn't present (on Win95 for example) */
|
||||
typedef BOOL (WINAPI *IsDebuggerPresentPtr)(VOID);
|
||||
IsDebuggerPresentPtr IsDebuggerPresent_ = 0;
|
||||
|
@ -1031,8 +1174,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
PaAsioHostApiRepresentation *asioHostApi;
|
||||
PaAsioDeviceInfo *deviceInfoArray;
|
||||
char **names;
|
||||
PaAsioDriverInfo paAsioDriverInfo;
|
||||
|
||||
asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) );
|
||||
if( !asioHostApi )
|
||||
{
|
||||
|
@ -1040,6 +1181,8 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
goto error;
|
||||
}
|
||||
|
||||
memset( asioHostApi, 0, sizeof(PaAsioHostApiRepresentation) ); /* ensure all fields are zeroed. especially asioHostApi->allocations */
|
||||
|
||||
/*
|
||||
We initialize COM ourselves here and uninitialize it in Terminate().
|
||||
This should be the only COM initialization needed in this module.
|
||||
|
@ -1142,7 +1285,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
|
||||
for( i=0; i < driverCount; ++i )
|
||||
{
|
||||
|
||||
PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i]));
|
||||
|
||||
// Since portaudio opens ALL ASIO drivers, and no one else does that,
|
||||
|
@ -1170,13 +1312,12 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
if( strcmp(names[i], "ASIO Digidesign Driver") == 0 )
|
||||
{
|
||||
PA_DEBUG(("BLACKLISTED!!! ASIO Digidesign Driver would quit the debugger\n"));
|
||||
continue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Attempt to load the asio driver... */
|
||||
if( LoadAsioDriver( asioHostApi, names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError )
|
||||
/* Attempt to init device info from the asio driver... */
|
||||
{
|
||||
PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
|
||||
PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
|
||||
|
@ -1185,119 +1326,17 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
deviceInfo->hostApi = hostApiIndex;
|
||||
|
||||
deviceInfo->name = names[i];
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", i,deviceInfo->name));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", i, paAsioDriverInfo.inputChannelCount));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", i, paAsioDriverInfo.outputChannelCount));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", i, paAsioDriverInfo.bufferMinSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", i, paAsioDriverInfo.bufferMaxSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", i, paAsioDriverInfo.bufferGranularity));
|
||||
|
||||
deviceInfo->maxInputChannels = paAsioDriverInfo.inputChannelCount;
|
||||
deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
|
||||
|
||||
deviceInfo->defaultSampleRate = 0.;
|
||||
bool foundDefaultSampleRate = false;
|
||||
for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
|
||||
if( InitPaDeviceInfoFromAsioDriver( asioHostApi, names[i], i, deviceInfo, asioDeviceInfo ) == paNoError )
|
||||
{
|
||||
ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
|
||||
if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
|
||||
{
|
||||
deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
|
||||
foundDefaultSampleRate = true;
|
||||
break;
|
||||
}
|
||||
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
|
||||
++(*hostApi)->info.deviceCount;
|
||||
}
|
||||
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate));
|
||||
|
||||
if( foundDefaultSampleRate ){
|
||||
|
||||
/* calculate default latency values from bufferPreferredSize
|
||||
for default low latency, and bufferMaxSize
|
||||
for default high latency.
|
||||
use the default sample rate to convert from samples to
|
||||
seconds. Without knowing what sample rate the user will
|
||||
use this is the best we can do.
|
||||
*/
|
||||
|
||||
double defaultLowLatency =
|
||||
paAsioDriverInfo.bufferPreferredSize / deviceInfo->defaultSampleRate;
|
||||
|
||||
deviceInfo->defaultLowInputLatency = defaultLowLatency;
|
||||
deviceInfo->defaultLowOutputLatency = defaultLowLatency;
|
||||
|
||||
double defaultHighLatency =
|
||||
paAsioDriverInfo.bufferMaxSize / deviceInfo->defaultSampleRate;
|
||||
|
||||
if( defaultHighLatency < defaultLowLatency )
|
||||
defaultHighLatency = defaultLowLatency; /* just in case the driver returns something strange */
|
||||
|
||||
deviceInfo->defaultHighInputLatency = defaultHighLatency;
|
||||
deviceInfo->defaultHighOutputLatency = defaultHighLatency;
|
||||
|
||||
}else{
|
||||
|
||||
deviceInfo->defaultLowInputLatency = 0.;
|
||||
deviceInfo->defaultLowOutputLatency = 0.;
|
||||
deviceInfo->defaultHighInputLatency = 0.;
|
||||
deviceInfo->defaultHighOutputLatency = 0.;
|
||||
else
|
||||
{
|
||||
PA_DEBUG(("Skipping ASIO device:%s\n",names[i]));
|
||||
continue;
|
||||
}
|
||||
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
|
||||
PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
|
||||
|
||||
asioDeviceInfo->minBufferSize = paAsioDriverInfo.bufferMinSize;
|
||||
asioDeviceInfo->maxBufferSize = paAsioDriverInfo.bufferMaxSize;
|
||||
asioDeviceInfo->preferredBufferSize = paAsioDriverInfo.bufferPreferredSize;
|
||||
asioDeviceInfo->bufferGranularity = paAsioDriverInfo.bufferGranularity;
|
||||
|
||||
|
||||
asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
|
||||
asioHostApi->allocations,
|
||||
sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
|
||||
+ deviceInfo->maxOutputChannels) );
|
||||
if( !asioDeviceInfo->asioChannelInfos )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error_unload;
|
||||
}
|
||||
|
||||
int a;
|
||||
|
||||
for( a=0; a < deviceInfo->maxInputChannels; ++a ){
|
||||
asioDeviceInfo->asioChannelInfos[a].channel = a;
|
||||
asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
|
||||
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
|
||||
if( asioError != ASE_OK )
|
||||
{
|
||||
result = paUnanticipatedHostError;
|
||||
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
|
||||
goto error_unload;
|
||||
}
|
||||
}
|
||||
|
||||
for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
|
||||
int b = deviceInfo->maxInputChannels + a;
|
||||
asioDeviceInfo->asioChannelInfos[b].channel = a;
|
||||
asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
|
||||
ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
|
||||
if( asioError != ASE_OK )
|
||||
{
|
||||
result = paUnanticipatedHostError;
|
||||
PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
|
||||
goto error_unload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* unload the driver */
|
||||
UnloadAsioDriver();
|
||||
|
||||
(*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
|
||||
++(*hostApi)->info.deviceCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1331,9 +1370,6 @@ PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex
|
|||
|
||||
return result;
|
||||
|
||||
error_unload:
|
||||
UnloadAsioDriver();
|
||||
|
||||
error:
|
||||
if( asioHostApi )
|
||||
{
|
||||
|
@ -1744,7 +1780,7 @@ static unsigned long SelectHostBufferSizeForSpecifiedUserFramesPerBuffer(
|
|||
do {
|
||||
if( (x % userFramesPerBuffer) == 0 )
|
||||
{
|
||||
/* any power-of-two multiple of userFramesPerBuffer is acceptable */
|
||||
/* any multiple of userFramesPerBuffer is acceptable */
|
||||
result = x;
|
||||
if( result >= targetBufferingLatencyFrames )
|
||||
break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */
|
||||
|
@ -1767,7 +1803,7 @@ static unsigned long SelectHostBufferSizeForSpecifiedUserFramesPerBuffer(
|
|||
do {
|
||||
if( (x % userFramesPerBuffer) == 0 )
|
||||
{
|
||||
/* any power-of-two multiple of userFramesPerBuffer is acceptable */
|
||||
/* any multiple of userFramesPerBuffer is acceptable */
|
||||
result = x;
|
||||
if( result >= targetBufferingLatencyFrames )
|
||||
break; /* stop. a value >= to targetBufferingLatencyFrames is ideal. */
|
||||
|
@ -2447,10 +2483,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor ,
|
||||
inputChannelCount ,
|
||||
inputSampleFormat & ~paNonInterleaved , /* Ring buffer. */
|
||||
hostInputSampleFormat , /* Host format. */
|
||||
(hostInputSampleFormat | paNonInterleaved), /* Host format. */
|
||||
outputChannelCount ,
|
||||
outputSampleFormat & ~paNonInterleaved, /* Ring buffer. */
|
||||
hostOutputSampleFormat , /* Host format. */
|
||||
(hostOutputSampleFormat | paNonInterleaved), /* Host format. */
|
||||
sampleRate ,
|
||||
streamFlags ,
|
||||
framesPerBuffer , /* Frames per ring buffer block. */
|
||||
|
@ -3046,7 +3082,7 @@ previousIndex = index;
|
|||
paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency;
|
||||
*/
|
||||
|
||||
/* Disabled! Stopping and re-starting the stream causes an input overflow / output undeflow. S.Fischer */
|
||||
/* Disabled! Stopping and re-starting the stream causes an input overflow / output underflow. S.Fischer */
|
||||
#if 0
|
||||
// detect underflows by checking inter-callback time > 2 buffer period
|
||||
static double previousTime = -1;
|
||||
|
@ -3498,6 +3534,7 @@ static PaError IsStreamActive( PaStream *s )
|
|||
static PaTime GetStreamTime( PaStream *s )
|
||||
{
|
||||
(void) s; /* unused parameter */
|
||||
|
||||
return (double)timeGetTime() * .001;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,87 +125,114 @@ static bool ensureChannelNameSize( int size )
|
|||
*/
|
||||
const char *PaMacCore_GetChannelName( int device, int channelIndex, bool input )
|
||||
{
|
||||
struct PaUtilHostApiRepresentation *hostApi;
|
||||
PaError err;
|
||||
OSStatus error;
|
||||
err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
|
||||
assert(err == paNoError);
|
||||
if( err != paNoError )
|
||||
return NULL;
|
||||
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
|
||||
AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device];
|
||||
|
||||
UInt32 size = 0;
|
||||
|
||||
error = AudioDeviceGetPropertyInfo( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyChannelName,
|
||||
&size,
|
||||
NULL );
|
||||
if( error ) {
|
||||
//try the CFString
|
||||
CFStringRef name;
|
||||
bool isDeviceName = false;
|
||||
size = sizeof( name );
|
||||
error = AudioDeviceGetProperty( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyChannelNameCFString,
|
||||
&size,
|
||||
&name );
|
||||
if( error ) { //as a last-ditch effort, get the device name. Later we'll append the channel number.
|
||||
size = sizeof( name );
|
||||
error = AudioDeviceGetProperty( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyDeviceNameCFString,
|
||||
&size,
|
||||
&name );
|
||||
if( error )
|
||||
return NULL;
|
||||
isDeviceName = true;
|
||||
}
|
||||
if( isDeviceName ) {
|
||||
name = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%@: %d"), name, channelIndex + 1 );
|
||||
}
|
||||
|
||||
CFIndex length = CFStringGetLength(name);
|
||||
while( ensureChannelNameSize( length * sizeof(UniChar) + 1 ) ) {
|
||||
if( CFStringGetCString( name, channelName, channelNameSize, kCFStringEncodingUTF8 ) ) {
|
||||
if( isDeviceName )
|
||||
CFRelease( name );
|
||||
return channelName;
|
||||
}
|
||||
if( length == 0 )
|
||||
++length;
|
||||
length *= 2;
|
||||
}
|
||||
if( isDeviceName )
|
||||
CFRelease( name );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//continue with C string:
|
||||
if( !ensureChannelNameSize( size ) )
|
||||
return NULL;
|
||||
|
||||
error = AudioDeviceGetProperty( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyChannelName,
|
||||
&size,
|
||||
channelName );
|
||||
|
||||
if( error ) {
|
||||
ERR( error );
|
||||
return NULL;
|
||||
}
|
||||
return channelName;
|
||||
struct PaUtilHostApiRepresentation *hostApi;
|
||||
PaError err;
|
||||
OSStatus error;
|
||||
err = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
|
||||
assert(err == paNoError);
|
||||
if( err != paNoError )
|
||||
return NULL;
|
||||
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
|
||||
AudioDeviceID hostApiDevice = macCoreHostApi->devIds[device];
|
||||
CFStringRef nameRef;
|
||||
|
||||
/* First try with CFString */
|
||||
UInt32 size = sizeof(nameRef);
|
||||
error = AudioDeviceGetProperty( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyChannelNameCFString,
|
||||
&size,
|
||||
&nameRef );
|
||||
if( error )
|
||||
{
|
||||
/* try the C String */
|
||||
size = 0;
|
||||
error = AudioDeviceGetPropertyInfo( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyChannelName,
|
||||
&size,
|
||||
NULL);
|
||||
if( !error )
|
||||
{
|
||||
if( !ensureChannelNameSize( size ) )
|
||||
return NULL;
|
||||
|
||||
error = AudioDeviceGetProperty( hostApiDevice,
|
||||
channelIndex + 1,
|
||||
input,
|
||||
kAudioDevicePropertyChannelName,
|
||||
&size,
|
||||
channelName );
|
||||
|
||||
|
||||
if( !error )
|
||||
return channelName;
|
||||
}
|
||||
|
||||
/* as a last-ditch effort, we use the device name and append the channel number. */
|
||||
nameRef = CFStringCreateWithFormat( NULL, NULL, CFSTR( "%s: %d"), hostApi->deviceInfos[device]->name, channelIndex + 1 );
|
||||
|
||||
|
||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);;
|
||||
if( !ensureChannelNameSize( size ) )
|
||||
{
|
||||
CFRelease( nameRef );
|
||||
return NULL;
|
||||
}
|
||||
CFStringGetCString( nameRef, channelName, size+1, kCFStringEncodingUTF8 );
|
||||
CFRelease( nameRef );
|
||||
}
|
||||
else
|
||||
{
|
||||
size = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);;
|
||||
if( !ensureChannelNameSize( size ) )
|
||||
{
|
||||
CFRelease( nameRef );
|
||||
return NULL;
|
||||
}
|
||||
CFStringGetCString( nameRef, channelName, size+1, kCFStringEncodingUTF8 );
|
||||
CFRelease( nameRef );
|
||||
}
|
||||
|
||||
return channelName;
|
||||
}
|
||||
|
||||
|
||||
PaError PaMacCore_GetBufferSizeRange( PaDeviceIndex device,
|
||||
long *minBufferSizeFrames, long *maxBufferSizeFrames )
|
||||
{
|
||||
PaError result;
|
||||
PaUtilHostApiRepresentation *hostApi;
|
||||
|
||||
result = PaUtil_GetHostApiRepresentation( &hostApi, paCoreAudio );
|
||||
|
||||
if( result == paNoError )
|
||||
{
|
||||
PaDeviceIndex hostApiDeviceIndex;
|
||||
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDeviceIndex, device, hostApi );
|
||||
if( result == paNoError )
|
||||
{
|
||||
PaMacAUHAL *macCoreHostApi = (PaMacAUHAL*)hostApi;
|
||||
AudioDeviceID macCoreDeviceId = macCoreHostApi->devIds[hostApiDeviceIndex];
|
||||
AudioValueRange audioRange;
|
||||
UInt32 propSize = sizeof( audioRange );
|
||||
|
||||
// return the size range for the output scope unless we only have inputs
|
||||
Boolean isInput = 0;
|
||||
if( macCoreHostApi->inheritedHostApiRep.deviceInfos[hostApiDeviceIndex]->maxOutputChannels == 0 )
|
||||
isInput = 1;
|
||||
|
||||
result = WARNING(AudioDeviceGetProperty( macCoreDeviceId, 0, isInput, kAudioDevicePropertyBufferFrameSizeRange, &propSize, &audioRange ) );
|
||||
|
||||
|
||||
*minBufferSizeFrames = audioRange.mMinimum;
|
||||
*maxBufferSizeFrames = audioRange.mMaximum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s )
|
||||
|
@ -280,7 +307,7 @@ static PaError OpenAndSetupOneAudioUnit(
|
|||
|
||||
/* for setting errors. */
|
||||
#define PA_AUHAL_SET_LAST_HOST_ERROR( errorCode, errorText ) \
|
||||
PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )
|
||||
PaUtil_SetLastHostErrorInfo( paCoreAudio, errorCode, errorText )
|
||||
|
||||
/*
|
||||
* Callback called when starting or stopping a stream.
|
||||
|
@ -625,26 +652,46 @@ static PaError InitializeDeviceInfo( PaMacAUHAL *auhalHostApi,
|
|||
Float64 sampleRate;
|
||||
char *name;
|
||||
PaError err = paNoError;
|
||||
CFStringRef nameRef;
|
||||
UInt32 propSize;
|
||||
|
||||
VVDBUG(("InitializeDeviceInfo(): macCoreDeviceId=%ld\n", macCoreDeviceId));
|
||||
|
||||
memset(deviceInfo, 0, sizeof(deviceInfo));
|
||||
memset(deviceInfo, 0, sizeof(PaDeviceInfo));
|
||||
|
||||
deviceInfo->structVersion = 2;
|
||||
deviceInfo->hostApi = hostApiIndex;
|
||||
|
||||
/* Get the device name. Fail if we can't get it. */
|
||||
err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
|
||||
|
||||
/* Get the device name using CFString */
|
||||
propSize = sizeof(nameRef);
|
||||
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceNameCFString, &propSize, &nameRef));
|
||||
if (err)
|
||||
return err;
|
||||
{
|
||||
/* Get the device name using c string. Fail if we can't get it. */
|
||||
err = ERR(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize);
|
||||
if ( !name )
|
||||
return paInsufficientMemory;
|
||||
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
|
||||
if (err)
|
||||
return err;
|
||||
name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations,propSize+1);
|
||||
if ( !name )
|
||||
return paInsufficientMemory;
|
||||
err = ERR(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* valid CFString so we just allocate a c string big enough to contain the data */
|
||||
propSize = CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef), kCFStringEncodingUTF8);
|
||||
name = PaUtil_GroupAllocateMemory(auhalHostApi->allocations, propSize+1);
|
||||
if ( !name )
|
||||
{
|
||||
CFRelease(nameRef);
|
||||
return paInsufficientMemory;
|
||||
}
|
||||
CFStringGetCString(nameRef, name, propSize+1, kCFStringEncodingUTF8);
|
||||
CFRelease(nameRef);
|
||||
}
|
||||
deviceInfo->name = name;
|
||||
|
||||
/* Try to get the default sample rate. Don't fail if we can't get this. */
|
||||
|
@ -990,18 +1037,19 @@ static void UpdateTimeStampOffsets( PaMacCoreStream *stream )
|
|||
}
|
||||
|
||||
/* ================================================================================= */
|
||||
/* Query sample rate property. */
|
||||
static OSStatus UpdateSampleRateFromDeviceProperty( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput )
|
||||
|
||||
/* can be used to update from nominal or actual sample rate */
|
||||
static OSStatus UpdateSampleRateFromDeviceProperty( PaMacCoreStream *stream, AudioDeviceID deviceID, Boolean isInput, AudioDevicePropertyID sampleRatePropertyID )
|
||||
{
|
||||
PaMacCoreDeviceProperties * deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties;
|
||||
/* FIXME: not sure if this should be the sample rate of the output device or the output unit */
|
||||
Float64 actualSampleRate = deviceProperties->sampleRate;
|
||||
|
||||
Float64 sampleRate = 0.0;
|
||||
UInt32 propSize = sizeof(Float64);
|
||||
OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, kAudioDevicePropertyActualSampleRate, &propSize, &actualSampleRate);
|
||||
if( (osErr == noErr) && (actualSampleRate > 1000.0) ) // avoid divide by zero if there's an error
|
||||
OSStatus osErr = AudioDeviceGetProperty( deviceID, 0, isInput, sampleRatePropertyID, &propSize, &sampleRate);
|
||||
if( (osErr == noErr) && (sampleRate > 1000.0) ) /* avoid divide by zero if there's an error */
|
||||
{
|
||||
deviceProperties->sampleRate = actualSampleRate;
|
||||
deviceProperties->samplePeriod = 1.0 / actualSampleRate;
|
||||
deviceProperties->sampleRate = sampleRate;
|
||||
deviceProperties->samplePeriod = 1.0 / sampleRate;
|
||||
}
|
||||
return osErr;
|
||||
}
|
||||
|
@ -1013,7 +1061,7 @@ static OSStatus AudioDevicePropertyActualSampleRateListenerProc( AudioDeviceID i
|
|||
// Make sure the callback is operating on a stream that is still valid!
|
||||
assert( stream->streamRepresentation.magic == PA_STREAM_MAGIC );
|
||||
|
||||
OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput );
|
||||
OSStatus osErr = UpdateSampleRateFromDeviceProperty( stream, inDevice, isInput, kAudioDevicePropertyActualSampleRate );
|
||||
if( osErr == noErr )
|
||||
{
|
||||
UpdateTimeStampOffsets( stream );
|
||||
|
@ -1077,9 +1125,6 @@ static OSStatus SetupDevicePropertyListeners( PaMacCoreStream *stream, AudioDevi
|
|||
OSStatus osErr = noErr;
|
||||
PaMacCoreDeviceProperties *deviceProperties = isInput ? &stream->inputProperties : &stream->outputProperties;
|
||||
|
||||
// Start with the current values for the device properties.
|
||||
UpdateSampleRateFromDeviceProperty( stream, deviceID, isInput );
|
||||
|
||||
if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput,
|
||||
kAudioDevicePropertyLatency, &deviceProperties->deviceLatency )) != noErr ) return osErr;
|
||||
if( (osErr = QueryUInt32DeviceProperty( deviceID, isInput,
|
||||
|
@ -1598,12 +1643,19 @@ static UInt32 CalculateOptimalBufferSize( PaMacAUHAL *auhalHostApi,
|
|||
resultBufferSizeFrames = MAX( resultBufferSizeFrames, (UInt32) variableLatencyFrames );
|
||||
}
|
||||
|
||||
// can't have zero frames. code to round up to next user buffer requires non-zero
|
||||
resultBufferSizeFrames = MAX( resultBufferSizeFrames, 1 );
|
||||
|
||||
if( requestedFramesPerBuffer != paFramesPerBufferUnspecified )
|
||||
{
|
||||
// make host buffer the next highest integer multiple of user frames per buffer
|
||||
UInt32 n = (resultBufferSizeFrames + requestedFramesPerBuffer - 1) / requestedFramesPerBuffer;
|
||||
resultBufferSizeFrames = n * requestedFramesPerBuffer;
|
||||
|
||||
|
||||
// FIXME: really we should be searching for a multiple of requestedFramesPerBuffer
|
||||
// that is >= suggested latency and also fits within device buffer min/max
|
||||
|
||||
}else{
|
||||
VDBUG( ("Block Size unspecified. Based on Latency, the user wants a Block Size near: %ld.\n",
|
||||
resultBufferSizeFrames ) );
|
||||
|
@ -1737,25 +1789,16 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
do is initialize everything so that if we fail, we know what hasn't
|
||||
been touched.
|
||||
*/
|
||||
|
||||
stream->inputAudioBufferList.mBuffers[0].mData = NULL;
|
||||
stream->inputRingBuffer.buffer = NULL;
|
||||
bzero( &stream->blio, sizeof( PaMacBlio ) );
|
||||
/*
|
||||
bzero( stream, sizeof( PaMacCoreStream ) );
|
||||
|
||||
/*
|
||||
stream->blio.inputRingBuffer.buffer = NULL;
|
||||
stream->blio.outputRingBuffer.buffer = NULL;
|
||||
stream->blio.inputSampleFormat = inputParameters?inputParameters->sampleFormat:0;
|
||||
stream->blio.inputSampleSize = computeSampleSizeFromFormat(stream->blio.inputSampleFormat);
|
||||
stream->blio.outputSampleFormat=outputParameters?outputParameters->sampleFormat:0;
|
||||
stream->blio.outputSampleSize = computeSampleSizeFromFormat(stream->blio.outputSampleFormat);
|
||||
*/
|
||||
stream->inputSRConverter = NULL;
|
||||
stream->inputUnit = NULL;
|
||||
stream->outputUnit = NULL;
|
||||
stream->inputFramesPerBuffer = 0;
|
||||
stream->outputFramesPerBuffer = 0;
|
||||
stream->bufferProcessorIsInitialized = FALSE;
|
||||
stream->timingInformationMutexIsInitialized = 0;
|
||||
*/
|
||||
|
||||
/* assert( streamCallback ) ; */ /* only callback mode is implemented */
|
||||
if( streamCallback )
|
||||
|
@ -1878,14 +1921,13 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
/*
|
||||
* If input and output devs are different or we are doing SR conversion,
|
||||
* we also need a
|
||||
* ring buffer to store inpt data while waiting for output
|
||||
* data.
|
||||
* we also need a ring buffer to store input data while waiting for
|
||||
* output data.
|
||||
*/
|
||||
if( (stream->outputUnit && (stream->inputUnit != stream->outputUnit))
|
||||
|| stream->inputSRConverter )
|
||||
{
|
||||
/* May want the ringSize ot initial position in
|
||||
/* May want the ringSize or initial position in
|
||||
ring buffer to depend somewhat on sample rate change */
|
||||
|
||||
void *data;
|
||||
|
@ -1908,7 +1950,15 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
}
|
||||
|
||||
/* now we can initialize the ring buffer */
|
||||
PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, szfl*inputParameters->channelCount, ringSize, data ) ;
|
||||
result = PaUtil_InitializeRingBuffer( &stream->inputRingBuffer, szfl*inputParameters->channelCount, ringSize, data );
|
||||
if( result != 0 )
|
||||
{
|
||||
/* The only reason this should fail is if ringSize is not a power of 2, which we do not anticipate happening. */
|
||||
result = paUnanticipatedHostError;
|
||||
free(data);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* advance the read point a little, so we are reading from the
|
||||
middle of the buffer */
|
||||
if( stream->outputUnit )
|
||||
|
@ -1930,12 +1980,11 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
stream->outputFramesPerBuffer,
|
||||
sampleRate );
|
||||
result = initializeBlioRingBuffers( &stream->blio,
|
||||
inputParameters?inputParameters->sampleFormat:0 ,
|
||||
outputParameters?outputParameters->sampleFormat:0 ,
|
||||
MAX(stream->inputFramesPerBuffer,stream->outputFramesPerBuffer),
|
||||
inputParameters ? inputParameters->sampleFormat : 0,
|
||||
outputParameters ? outputParameters->sampleFormat : 0,
|
||||
ringSize,
|
||||
inputParameters?inputChannelCount:0 ,
|
||||
outputParameters?outputChannelCount:0 ) ;
|
||||
inputParameters ? inputChannelCount : 0,
|
||||
outputParameters ? outputChannelCount : 0 ) ;
|
||||
if( result != paNoError )
|
||||
goto error;
|
||||
|
||||
|
@ -1993,53 +2042,48 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
|
||||
|
||||
stream->sampleRate = sampleRate;
|
||||
stream->outDeviceSampleRate = 0;
|
||||
if( stream->outputUnit ) {
|
||||
Float64 rate;
|
||||
UInt32 size = sizeof( rate );
|
||||
result = ERR( AudioDeviceGetProperty( stream->outputDevice,
|
||||
0,
|
||||
FALSE,
|
||||
kAudioDevicePropertyNominalSampleRate,
|
||||
&size, &rate ) );
|
||||
if( result )
|
||||
goto error;
|
||||
stream->outDeviceSampleRate = rate;
|
||||
}
|
||||
stream->inDeviceSampleRate = 0;
|
||||
if( stream->inputUnit ) {
|
||||
Float64 rate;
|
||||
UInt32 size = sizeof( rate );
|
||||
result = ERR( AudioDeviceGetProperty( stream->inputDevice,
|
||||
0,
|
||||
TRUE,
|
||||
kAudioDevicePropertyNominalSampleRate,
|
||||
&size, &rate ) );
|
||||
if( result )
|
||||
goto error;
|
||||
stream->inDeviceSampleRate = rate;
|
||||
}
|
||||
stream->sampleRate = sampleRate;
|
||||
|
||||
stream->userInChan = inputChannelCount;
|
||||
stream->userOutChan = outputChannelCount;
|
||||
|
||||
// Setup property listeners for timestamp and latency calculations.
|
||||
pthread_mutex_init( &stream->timingInformationMutex, NULL );
|
||||
stream->timingInformationMutexIsInitialized = 1;
|
||||
InitializeDeviceProperties( &stream->inputProperties );
|
||||
InitializeDeviceProperties( &stream->outputProperties );
|
||||
InitializeDeviceProperties( &stream->inputProperties ); // zeros the struct. doesn't actually init it to useful values
|
||||
InitializeDeviceProperties( &stream->outputProperties ); // zeros the struct. doesn't actually init it to useful values
|
||||
if( stream->outputUnit )
|
||||
{
|
||||
Boolean isInput = FALSE;
|
||||
|
||||
// Start with the current values for the device properties.
|
||||
// Init with nominal sample rate. Use actual sample rate where available
|
||||
|
||||
result = ERR( UpdateSampleRateFromDeviceProperty(
|
||||
stream, stream->outputDevice, isInput, kAudioDevicePropertyNominalSampleRate ) );
|
||||
if( result )
|
||||
goto error; /* fail if we can't even get a nominal device sample rate */
|
||||
|
||||
UpdateSampleRateFromDeviceProperty( stream, stream->outputDevice, isInput, kAudioDevicePropertyActualSampleRate );
|
||||
|
||||
SetupDevicePropertyListeners( stream, stream->outputDevice, isInput );
|
||||
}
|
||||
if( stream->inputUnit )
|
||||
{
|
||||
Boolean isInput = TRUE;
|
||||
|
||||
// as above
|
||||
result = ERR( UpdateSampleRateFromDeviceProperty(
|
||||
stream, stream->inputDevice, isInput, kAudioDevicePropertyNominalSampleRate ) );
|
||||
if( result )
|
||||
goto error;
|
||||
|
||||
UpdateSampleRateFromDeviceProperty( stream, stream->inputDevice, isInput, kAudioDevicePropertyActualSampleRate );
|
||||
|
||||
SetupDevicePropertyListeners( stream, stream->inputDevice, isInput );
|
||||
}
|
||||
UpdateTimeStampOffsets( stream );
|
||||
// Setup copies to be used by audio callback.
|
||||
// Setup timestamp copies to be used by audio callback.
|
||||
stream->timestampOffsetCombined_ioProcCopy = stream->timestampOffsetCombined;
|
||||
stream->timestampOffsetInputDevice_ioProcCopy = stream->timestampOffsetInputDevice;
|
||||
stream->timestampOffsetOutputDevice_ioProcCopy = stream->timestampOffsetOutputDevice;
|
||||
|
@ -2113,11 +2157,11 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
const bool isRender = inBusNumber == OUTPUT_ELEMENT;
|
||||
int callbackResult = paContinue ;
|
||||
double hostTimeStampInPaTime = HOST_TIME_TO_PA_TIME(inTimeStamp->mHostTime);
|
||||
|
||||
|
||||
VVDBUG(("AudioIOProc()\n"));
|
||||
|
||||
PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------*\
|
||||
This output may be useful for debugging,
|
||||
But printing durring the callback is a bad enough idea that
|
||||
|
@ -2218,7 +2262,8 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
*
|
||||
*/
|
||||
OSStatus err = 0;
|
||||
unsigned long frames;
|
||||
unsigned long frames;
|
||||
long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
|
||||
/* -- start processing -- */
|
||||
PaUtil_BeginBufferProcessing( &(stream->bufferProcessor),
|
||||
|
@ -2229,8 +2274,8 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
/* -- compute frames. do some checks -- */
|
||||
assert( ioData->mNumberBuffers == 1 );
|
||||
assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );
|
||||
frames = ioData->mBuffers[0].mDataByteSize;
|
||||
frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
|
||||
frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame;
|
||||
/* -- copy and process input data -- */
|
||||
err= AudioUnitRender(stream->inputUnit,
|
||||
ioActionFlags,
|
||||
|
@ -2238,9 +2283,10 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
INPUT_ELEMENT,
|
||||
inNumberFrames,
|
||||
&stream->inputAudioBufferList );
|
||||
/* FEEDBACK: I'm not sure what to do when this call fails. There's nothing in the PA API to
|
||||
* do about failures in the callback system. */
|
||||
assert( !err );
|
||||
if(err != noErr)
|
||||
{
|
||||
goto stop_stream;
|
||||
}
|
||||
|
||||
PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
|
||||
PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
|
||||
|
@ -2268,7 +2314,8 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
* and into the PA buffer processor. If sample rate conversion
|
||||
* is required on input, that is done here as well.
|
||||
*/
|
||||
unsigned long frames;
|
||||
unsigned long frames;
|
||||
long bytesPerFrame = sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
|
||||
/* Sometimes, when stopping a duplex stream we get erroneous
|
||||
xrun flags, so if this is our last run, clear the flags. */
|
||||
|
@ -2290,8 +2337,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
|
||||
/* -- Copy and process output data -- */
|
||||
assert( ioData->mNumberBuffers == 1 );
|
||||
frames = ioData->mBuffers[0].mDataByteSize;
|
||||
frames /= sizeof( float ) * ioData->mBuffers[0].mNumberChannels;
|
||||
frames = ioData->mBuffers[0].mDataByteSize / bytesPerFrame;
|
||||
assert( ioData->mBuffers[0].mNumberChannels == stream->userOutChan );
|
||||
PaUtil_SetOutputFrameCount( &(stream->bufferProcessor), frames );
|
||||
PaUtil_SetInterleavedOutputChannels( &(stream->bufferProcessor),
|
||||
|
@ -2305,6 +2351,8 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
/* Here, we read the data out of the ring buffer, through the
|
||||
audio converter. */
|
||||
int inChan = stream->inputAudioBufferList.mBuffers[0].mNumberChannels;
|
||||
long bytesPerFrame = flsz * inChan;
|
||||
|
||||
if( stream->inputSRConverter )
|
||||
{
|
||||
OSStatus err;
|
||||
|
@ -2318,14 +2366,22 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
&size,
|
||||
(void *)&data );
|
||||
if( err == RING_BUFFER_EMPTY )
|
||||
{ /*the ring buffer callback underflowed */
|
||||
{ /* the ring buffer callback underflowed */
|
||||
err = 0;
|
||||
bzero( ((char *)data) + size, sizeof(data)-size );
|
||||
stream->xrunFlags |= paInputUnderflow;
|
||||
/* The ring buffer can underflow normally when the stream is stopping.
|
||||
* So only report an error if the stream is active. */
|
||||
if( stream->state == ACTIVE )
|
||||
{
|
||||
stream->xrunFlags |= paInputUnderflow;
|
||||
}
|
||||
}
|
||||
ERR( err );
|
||||
assert( !err );
|
||||
|
||||
if(err != noErr)
|
||||
{
|
||||
goto stop_stream;
|
||||
}
|
||||
|
||||
PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
|
||||
PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
|
||||
0,
|
||||
|
@ -2342,7 +2398,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
AudioConverter would otherwise handle for us. */
|
||||
void *data1, *data2;
|
||||
ring_buffer_size_t size1, size2;
|
||||
PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer,
|
||||
ring_buffer_size_t framesReadable = PaUtil_GetRingBufferReadRegions( &stream->inputRingBuffer,
|
||||
frames,
|
||||
&data1, &size1,
|
||||
&data2, &size2 );
|
||||
|
@ -2357,14 +2413,21 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
|
||||
&callbackResult );
|
||||
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1 );
|
||||
} else if( size1 + size2 < frames ) {
|
||||
} else if( framesReadable < frames ) {
|
||||
|
||||
long sizeBytes1 = size1 * bytesPerFrame;
|
||||
long sizeBytes2 = size2 * bytesPerFrame;
|
||||
/*we underflowed. take what data we can, zero the rest.*/
|
||||
unsigned char data[frames*inChan*flsz];
|
||||
if( size1 )
|
||||
memcpy( data, data1, size1 );
|
||||
if( size2 )
|
||||
memcpy( data+size1, data2, size2 );
|
||||
bzero( data+size1+size2, frames*flsz*inChan - size1 - size2 );
|
||||
unsigned char data[ frames * bytesPerFrame ];
|
||||
if( size1 > 0 )
|
||||
{
|
||||
memcpy( data, data1, sizeBytes1 );
|
||||
}
|
||||
if( size2 > 0 )
|
||||
{
|
||||
memcpy( data+sizeBytes1, data2, sizeBytes2 );
|
||||
}
|
||||
bzero( data+sizeBytes1+sizeBytes2, (frames*bytesPerFrame) - sizeBytes1 - sizeBytes2 );
|
||||
|
||||
PaUtil_SetInputFrameCount( &(stream->bufferProcessor), frames );
|
||||
PaUtil_SetInterleavedInputChannels( &(stream->bufferProcessor),
|
||||
|
@ -2375,7 +2438,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
|
||||
&callbackResult );
|
||||
PaUtil_AdvanceRingBufferReadIndex( &stream->inputRingBuffer,
|
||||
size1+size2 );
|
||||
framesReadable );
|
||||
/* flag underflow */
|
||||
stream->xrunFlags |= paInputUnderflow;
|
||||
} else {
|
||||
|
@ -2393,7 +2456,7 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
framesProcessed =
|
||||
PaUtil_EndBufferProcessing( &(stream->bufferProcessor),
|
||||
&callbackResult );
|
||||
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, size1+size2 );
|
||||
PaUtil_AdvanceRingBufferReadIndex(&stream->inputRingBuffer, framesReadable );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -2424,20 +2487,23 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
if( err == -10874 )
|
||||
inNumberFrames /= 2;
|
||||
} while( err == -10874 && inNumberFrames > 1 );
|
||||
/* FEEDBACK: I'm not sure what to do when this call fails */
|
||||
ERR( err );
|
||||
assert( !err );
|
||||
if(err != noErr)
|
||||
{
|
||||
goto stop_stream;
|
||||
}
|
||||
|
||||
if( stream->inputSRConverter || stream->outputUnit )
|
||||
{
|
||||
/* If this is duplex or we use a converter, put the data
|
||||
into the ring buffer. */
|
||||
long bytesIn, bytesOut;
|
||||
bytesIn = sizeof( float ) * inNumberFrames * chan;
|
||||
bytesOut = PaUtil_WriteRingBuffer( &stream->inputRingBuffer,
|
||||
ring_buffer_size_t framesWritten = PaUtil_WriteRingBuffer( &stream->inputRingBuffer,
|
||||
stream->inputAudioBufferList.mBuffers[0].mData,
|
||||
inNumberFrames );
|
||||
if( bytesIn != bytesOut )
|
||||
stream->xrunFlags |= paInputOverflow ;
|
||||
if( framesWritten != inNumberFrames )
|
||||
{
|
||||
stream->xrunFlags |= paInputOverflow ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2469,11 +2535,11 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
* chunks, and let the BufferProcessor deal with the rest.
|
||||
*
|
||||
*/
|
||||
/*This might be too big or small depending on SR conversion*/
|
||||
/* This might be too big or small depending on SR conversion. */
|
||||
float data[ chan * inNumberFrames ];
|
||||
OSStatus err;
|
||||
do
|
||||
{ /*Run the buffer processor until we are out of data*/
|
||||
{ /* Run the buffer processor until we are out of data. */
|
||||
UInt32 size;
|
||||
long f;
|
||||
|
||||
|
@ -2486,7 +2552,11 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
(void *)data );
|
||||
if( err != RING_BUFFER_EMPTY )
|
||||
ERR( err );
|
||||
assert( err == 0 || err == RING_BUFFER_EMPTY );
|
||||
if( err != noErr && err != RING_BUFFER_EMPTY )
|
||||
{
|
||||
goto stop_stream;
|
||||
}
|
||||
|
||||
|
||||
f = size / ( chan * sizeof(float) );
|
||||
PaUtil_SetInputFrameCount( &(stream->bufferProcessor), f );
|
||||
|
@ -2509,24 +2579,24 @@ static OSStatus AudioIOProc( void *inRefCon,
|
|||
}
|
||||
}
|
||||
|
||||
switch( callbackResult )
|
||||
{
|
||||
case paContinue: break;
|
||||
case paComplete:
|
||||
case paAbort:
|
||||
stream->state = CALLBACK_STOPPED ;
|
||||
if( stream->outputUnit )
|
||||
AudioOutputUnitStop(stream->outputUnit);
|
||||
if( stream->inputUnit )
|
||||
AudioOutputUnitStop(stream->inputUnit);
|
||||
break;
|
||||
}
|
||||
// Should we return successfully or fall through to stopping the stream?
|
||||
if( callbackResult == paContinue )
|
||||
{
|
||||
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
|
||||
return noErr;
|
||||
}
|
||||
|
||||
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
|
||||
return noErr;
|
||||
stop_stream:
|
||||
stream->state = CALLBACK_STOPPED ;
|
||||
if( stream->outputUnit )
|
||||
AudioOutputUnitStop(stream->outputUnit);
|
||||
if( stream->inputUnit )
|
||||
AudioOutputUnitStop(stream->inputUnit);
|
||||
|
||||
PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
When CloseStream() is called, the multi-api layer ensures that
|
||||
the stream has already been stopped or aborted.
|
||||
|
@ -2654,18 +2724,10 @@ static ComponentResult BlockWhileAudioUnitIsRunning( AudioUnit audioUnit, AudioU
|
|||
return noErr;
|
||||
}
|
||||
|
||||
static PaError StopStream( PaStream *s )
|
||||
static PaError FinishStoppingStream( PaMacCoreStream *stream )
|
||||
{
|
||||
PaMacCoreStream *stream = (PaMacCoreStream*)s;
|
||||
OSStatus result = noErr;
|
||||
PaError paErr;
|
||||
VVDBUG(("StopStream()\n"));
|
||||
|
||||
VDBUG( ("Waiting for BLIO.\n") );
|
||||
waitUntilBlioWriteBufferIsFlushed( &stream->blio );
|
||||
VDBUG( ( "Stopping stream.\n" ) );
|
||||
|
||||
stream->state = STOPPING;
|
||||
|
||||
#define ERR_WRAP(mac_err) do { result = mac_err ; if ( result != noErr ) return ERR(result) ; } while(0)
|
||||
/* -- stop and reset -- */
|
||||
|
@ -2717,12 +2779,34 @@ static PaError StopStream( PaStream *s )
|
|||
#undef ERR_WRAP
|
||||
}
|
||||
|
||||
/* Block until buffer is empty then stop the stream. */
|
||||
static PaError StopStream( PaStream *s )
|
||||
{
|
||||
PaError paErr;
|
||||
PaMacCoreStream *stream = (PaMacCoreStream*)s;
|
||||
VVDBUG(("StopStream()\n"));
|
||||
|
||||
/* Tell WriteStream to stop filling the buffer. */
|
||||
stream->state = STOPPING;
|
||||
|
||||
if( stream->userOutChan > 0 ) /* Does this stream do output? */
|
||||
{
|
||||
size_t maxHostFrames = MAX( stream->inputFramesPerBuffer, stream->outputFramesPerBuffer );
|
||||
VDBUG( ("Waiting for write buffer to be drained.\n") );
|
||||
paErr = waitUntilBlioWriteBufferIsEmpty( &stream->blio, stream->sampleRate,
|
||||
maxHostFrames );
|
||||
VDBUG( ( "waitUntilBlioWriteBufferIsEmpty returned %d\n", paErr ) );
|
||||
}
|
||||
return FinishStoppingStream( stream );
|
||||
}
|
||||
|
||||
/* Immediately stop the stream. */
|
||||
static PaError AbortStream( PaStream *s )
|
||||
{
|
||||
VVDBUG(("AbortStream()->StopStream()\n"));
|
||||
VDBUG( ( "Aborting stream.\n" ) );
|
||||
/* We have nothing faster than StopStream. */
|
||||
return StopStream(s);
|
||||
PaMacCoreStream *stream = (PaMacCoreStream*)s;
|
||||
VDBUG( ( "AbortStream()\n" ) );
|
||||
stream->state = STOPPING;
|
||||
return FinishStoppingStream( stream );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -108,14 +108,16 @@ static size_t computeSampleSizeFromFormatPow2( PaSampleFormat format )
|
|||
*
|
||||
*/
|
||||
|
||||
/* This should be called with the relevant info when initializing a stream for
|
||||
callback. */
|
||||
/**
|
||||
* This should be called with the relevant info when initializing a stream for callback.
|
||||
*
|
||||
* @param ringBufferSizeInFrames must be a power of 2
|
||||
*/
|
||||
PaError initializeBlioRingBuffers(
|
||||
PaMacBlio *blio,
|
||||
PaSampleFormat inputSampleFormat,
|
||||
PaSampleFormat outputSampleFormat,
|
||||
size_t framesPerBuffer,
|
||||
long ringBufferSize,
|
||||
long ringBufferSizeInFrames,
|
||||
int inChan,
|
||||
int outChan )
|
||||
{
|
||||
|
@ -126,20 +128,19 @@ PaError initializeBlioRingBuffers(
|
|||
/* zeroify things */
|
||||
bzero( blio, sizeof( PaMacBlio ) );
|
||||
/* this is redundant, but the buffers are used to check
|
||||
if the bufffers have been initialized, so we do it explicitly. */
|
||||
if the buffers have been initialized, so we do it explicitly. */
|
||||
blio->inputRingBuffer.buffer = NULL;
|
||||
blio->outputRingBuffer.buffer = NULL;
|
||||
|
||||
/* initialize simple data */
|
||||
blio->ringBufferFrames = ringBufferSize;
|
||||
blio->ringBufferFrames = ringBufferSizeInFrames;
|
||||
blio->inputSampleFormat = inputSampleFormat;
|
||||
blio->inputSampleSizeActual = computeSampleSizeFromFormat(inputSampleFormat);
|
||||
blio->inputSampleSizePow2 = computeSampleSizeFromFormatPow2(inputSampleFormat);
|
||||
blio->inputSampleSizePow2 = computeSampleSizeFromFormatPow2(inputSampleFormat); // FIXME: WHY?
|
||||
blio->outputSampleFormat = outputSampleFormat;
|
||||
blio->outputSampleSizeActual = computeSampleSizeFromFormat(outputSampleFormat);
|
||||
blio->outputSampleSizePow2 = computeSampleSizeFromFormatPow2(outputSampleFormat);
|
||||
|
||||
blio->framesPerBuffer = framesPerBuffer;
|
||||
blio->inChan = inChan;
|
||||
blio->outChan = outChan;
|
||||
blio->statusFlags = 0;
|
||||
|
@ -163,7 +164,7 @@ PaError initializeBlioRingBuffers(
|
|||
result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) );
|
||||
#endif
|
||||
if( inChan ) {
|
||||
data = calloc( ringBufferSize, blio->inputSampleSizePow2*inChan );
|
||||
data = calloc( ringBufferSizeInFrames, blio->inputSampleSizePow2 * inChan );
|
||||
if( !data )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
@ -172,12 +173,13 @@ PaError initializeBlioRingBuffers(
|
|||
|
||||
err = PaUtil_InitializeRingBuffer(
|
||||
&blio->inputRingBuffer,
|
||||
1, ringBufferSize*blio->inputSampleSizePow2*inChan,
|
||||
blio->inputSampleSizePow2 * inChan,
|
||||
ringBufferSizeInFrames,
|
||||
data );
|
||||
assert( !err );
|
||||
}
|
||||
if( outChan ) {
|
||||
data = calloc( ringBufferSize, blio->outputSampleSizePow2*outChan );
|
||||
data = calloc( ringBufferSizeInFrames, blio->outputSampleSizePow2 * outChan );
|
||||
if( !data )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
|
@ -186,7 +188,8 @@ PaError initializeBlioRingBuffers(
|
|||
|
||||
err = PaUtil_InitializeRingBuffer(
|
||||
&blio->outputRingBuffer,
|
||||
1, ringBufferSize*blio->outputSampleSizePow2*outChan,
|
||||
blio->outputSampleSizePow2 * outChan,
|
||||
ringBufferSizeInFrames,
|
||||
data );
|
||||
assert( !err );
|
||||
}
|
||||
|
@ -266,12 +269,11 @@ PaError resetBlioRingBuffers( PaMacBlio *blio )
|
|||
#endif
|
||||
blio->statusFlags = 0;
|
||||
if( blio->outputRingBuffer.buffer ) {
|
||||
PaUtil_FlushRingBuffer( &blio->outputRingBuffer );
|
||||
bzero( blio->outputRingBuffer.buffer,
|
||||
blio->outputRingBuffer.bufferSize );
|
||||
/* Advance buffer */
|
||||
PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->ringBufferFrames*blio->outputSampleSizeActual*blio->outChan );
|
||||
//PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize );
|
||||
PaUtil_FlushRingBuffer( &blio->outputRingBuffer );
|
||||
/* Fill the buffer with zeros. */
|
||||
bzero( blio->outputRingBuffer.buffer,
|
||||
blio->outputRingBuffer.bufferSize * blio->outputRingBuffer.elementSizeBytes );
|
||||
PaUtil_AdvanceRingBufferWriteIndex( &blio->outputRingBuffer, blio->ringBufferFrames );
|
||||
|
||||
/* Update isOutputFull. */
|
||||
#ifdef PA_MAC__BLIO_MUTEX
|
||||
|
@ -280,16 +282,14 @@ PaError resetBlioRingBuffers( PaMacBlio *blio )
|
|||
goto error;
|
||||
#endif
|
||||
/*
|
||||
printf( "------%d\n" , blio->framesPerBuffer );
|
||||
printf( "------%d\n" , blio->outChan );
|
||||
printf( "------%d\n" , blio->outputSampleSize );
|
||||
printf( "------%d\n" , blio->framesPerBuffer*blio->outChan*blio->outputSampleSize );
|
||||
*/
|
||||
}
|
||||
if( blio->inputRingBuffer.buffer ) {
|
||||
PaUtil_FlushRingBuffer( &blio->inputRingBuffer );
|
||||
bzero( blio->inputRingBuffer.buffer,
|
||||
blio->inputRingBuffer.bufferSize );
|
||||
blio->inputRingBuffer.bufferSize * blio->inputRingBuffer.elementSizeBytes );
|
||||
/* Update isInputEmpty. */
|
||||
#ifdef PA_MAC__BLIO_MUTEX
|
||||
result = blioSetIsInputEmpty( blio, true );
|
||||
|
@ -344,29 +344,32 @@ int BlioCallback( const void *input, void *output, unsigned long frameCount,
|
|||
void *userData )
|
||||
{
|
||||
PaMacBlio *blio = (PaMacBlio*)userData;
|
||||
long avail;
|
||||
long toRead;
|
||||
long toWrite;
|
||||
long read;
|
||||
long written;
|
||||
ring_buffer_size_t framesAvailable;
|
||||
ring_buffer_size_t framesToTransfer;
|
||||
ring_buffer_size_t framesTransferred;
|
||||
|
||||
/* set flags returned by OS: */
|
||||
OSAtomicOr32( statusFlags, &blio->statusFlags ) ;
|
||||
|
||||
/* --- Handle Input Buffer --- */
|
||||
if( blio->inChan ) {
|
||||
avail = PaUtil_GetRingBufferWriteAvailable( &blio->inputRingBuffer );
|
||||
framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->inputRingBuffer );
|
||||
|
||||
/* check for underflow */
|
||||
if( avail < frameCount * blio->inputSampleSizeActual * blio->inChan )
|
||||
OSAtomicOr32( paInputOverflow, &blio->statusFlags );
|
||||
if( framesAvailable < frameCount )
|
||||
{
|
||||
OSAtomicOr32( paInputOverflow, &blio->statusFlags );
|
||||
framesToTransfer = framesAvailable;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToTransfer = (ring_buffer_size_t)frameCount;
|
||||
}
|
||||
|
||||
toRead = MIN( avail, frameCount * blio->inputSampleSizeActual * blio->inChan );
|
||||
|
||||
/* copy the data */
|
||||
/* Copy the data from the audio input to the application ring buffer. */
|
||||
/*printf( "reading %d\n", toRead );*/
|
||||
read = PaUtil_WriteRingBuffer( &blio->inputRingBuffer, input, toRead );
|
||||
assert( toRead == read );
|
||||
framesTransferred = PaUtil_WriteRingBuffer( &blio->inputRingBuffer, input, framesToTransfer );
|
||||
assert( framesToTransfer == framesTransferred );
|
||||
#ifdef PA_MAC__BLIO_MUTEX
|
||||
/* Priority inversion. See notes below. */
|
||||
blioSetIsInputEmpty( blio, false );
|
||||
|
@ -376,21 +379,31 @@ int BlioCallback( const void *input, void *output, unsigned long frameCount,
|
|||
|
||||
/* --- Handle Output Buffer --- */
|
||||
if( blio->outChan ) {
|
||||
avail = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
|
||||
framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
|
||||
|
||||
/* check for underflow */
|
||||
if( avail < frameCount * blio->outputSampleSizeActual * blio->outChan )
|
||||
OSAtomicOr32( paOutputUnderflow, &blio->statusFlags );
|
||||
if( framesAvailable < frameCount )
|
||||
{
|
||||
/* zero out the end of the output buffer that we do not have data for */
|
||||
framesToTransfer = framesAvailable;
|
||||
|
||||
toWrite = MIN( avail, frameCount * blio->outputSampleSizeActual * blio->outChan );
|
||||
size_t bytesPerFrame = blio->outputSampleSizeActual * blio->outChan;
|
||||
size_t offsetInBytes = framesToTransfer * bytesPerFrame;
|
||||
size_t countInBytes = (frameCount - framesToTransfer) * bytesPerFrame;
|
||||
bzero( ((char *)output) + offsetInBytes, countInBytes );
|
||||
|
||||
OSAtomicOr32( paOutputUnderflow, &blio->statusFlags );
|
||||
framesToTransfer = framesAvailable;
|
||||
}
|
||||
else
|
||||
{
|
||||
framesToTransfer = (ring_buffer_size_t)frameCount;
|
||||
}
|
||||
|
||||
if( toWrite != frameCount * blio->outputSampleSizeActual * blio->outChan )
|
||||
bzero( ((char *)output)+toWrite,
|
||||
frameCount * blio->outputSampleSizeActual * blio->outChan - toWrite );
|
||||
/* copy the data */
|
||||
/*printf( "writing %d\n", toWrite );*/
|
||||
written = PaUtil_ReadRingBuffer( &blio->outputRingBuffer, output, toWrite );
|
||||
assert( toWrite == written );
|
||||
framesTransferred = PaUtil_ReadRingBuffer( &blio->outputRingBuffer, output, framesToTransfer );
|
||||
assert( framesToTransfer == framesTransferred );
|
||||
#ifdef PA_MAC__BLIO_MUTEX
|
||||
/* We have a priority inversion here. However, we will only have to
|
||||
wait if this was true and is now false, which means we've got
|
||||
|
@ -405,24 +418,25 @@ int BlioCallback( const void *input, void *output, unsigned long frameCount,
|
|||
|
||||
PaError ReadStream( PaStream* stream,
|
||||
void *buffer,
|
||||
unsigned long frames )
|
||||
unsigned long framesRequested )
|
||||
{
|
||||
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
|
||||
char *cbuf = (char *) buffer;
|
||||
PaError ret = paNoError;
|
||||
VVDBUG(("ReadStream()\n"));
|
||||
|
||||
while( frames > 0 ) {
|
||||
long avail;
|
||||
long toRead;
|
||||
while( framesRequested > 0 ) {
|
||||
ring_buffer_size_t framesAvailable;
|
||||
ring_buffer_size_t framesToTransfer;
|
||||
ring_buffer_size_t framesTransferred;
|
||||
do {
|
||||
avail = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
|
||||
framesAvailable = PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
|
||||
/*
|
||||
printf( "Read Buffer is %%%g full: %ld of %ld.\n",
|
||||
100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
|
||||
avail, blio->inputRingBuffer.bufferSize );
|
||||
framesAvailable, blio->inputRingBuffer.bufferSize );
|
||||
*/
|
||||
if( avail == 0 ) {
|
||||
if( framesAvailable == 0 ) {
|
||||
#ifdef PA_MAC_BLIO_MUTEX
|
||||
/**block when empty*/
|
||||
ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
|
||||
|
@ -440,14 +454,13 @@ PaError ReadStream( PaStream* stream,
|
|||
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
|
||||
#endif
|
||||
}
|
||||
} while( avail == 0 );
|
||||
toRead = MIN( avail, frames * blio->inputSampleSizeActual * blio->inChan );
|
||||
toRead -= toRead % blio->inputSampleSizeActual * blio->inChan ;
|
||||
PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, toRead );
|
||||
cbuf += toRead;
|
||||
frames -= toRead / ( blio->inputSampleSizeActual * blio->inChan );
|
||||
} while( framesAvailable == 0 );
|
||||
framesToTransfer = (ring_buffer_size_t) MIN( framesAvailable, framesRequested );
|
||||
framesTransferred = PaUtil_ReadRingBuffer( &blio->inputRingBuffer, (void *)cbuf, framesToTransfer );
|
||||
cbuf += framesTransferred * blio->inputSampleSizeActual * blio->inChan;
|
||||
framesRequested -= framesTransferred;
|
||||
|
||||
if( toRead == avail ) {
|
||||
if( framesToTransfer == framesAvailable ) {
|
||||
#ifdef PA_MAC_BLIO_MUTEX
|
||||
/* we just emptied the buffer, so we need to mark it as empty. */
|
||||
ret = blioSetIsInputEmpty( blio, true );
|
||||
|
@ -456,8 +469,10 @@ PaError ReadStream( PaStream* stream,
|
|||
/* of course, in the meantime, the callback may have put some sats
|
||||
in, so
|
||||
so check for that, too, to avoid a race condition. */
|
||||
/* FIXME - this does not seem to fix any race condition. */
|
||||
if( PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer ) ) {
|
||||
blioSetIsInputEmpty( blio, false );
|
||||
/* FIXME - why check? ret has not been set? */
|
||||
if( ret )
|
||||
return ret;
|
||||
}
|
||||
|
@ -467,6 +482,7 @@ PaError ReadStream( PaStream* stream,
|
|||
|
||||
/* Report either paNoError or paInputOverflowed. */
|
||||
/* may also want to report other errors, but this is non-standard. */
|
||||
/* FIXME should not clobber ret, use if(blio->statusFlags & paInputOverflow) */
|
||||
ret = blio->statusFlags & paInputOverflow;
|
||||
|
||||
/* report underflow only once: */
|
||||
|
@ -481,25 +497,27 @@ PaError ReadStream( PaStream* stream,
|
|||
|
||||
PaError WriteStream( PaStream* stream,
|
||||
const void *buffer,
|
||||
unsigned long frames )
|
||||
unsigned long framesRequested )
|
||||
{
|
||||
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
|
||||
PaMacCoreStream *macStream = (PaMacCoreStream*)stream;
|
||||
PaMacBlio *blio = &macStream->blio;
|
||||
char *cbuf = (char *) buffer;
|
||||
PaError ret = paNoError;
|
||||
VVDBUG(("WriteStream()\n"));
|
||||
|
||||
while( frames > 0 ) {
|
||||
long avail = 0;
|
||||
long toWrite;
|
||||
while( framesRequested > 0 && macStream->state != STOPPING ) {
|
||||
ring_buffer_size_t framesAvailable;
|
||||
ring_buffer_size_t framesToTransfer;
|
||||
ring_buffer_size_t framesTransferred;
|
||||
|
||||
do {
|
||||
avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
|
||||
framesAvailable = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
|
||||
/*
|
||||
printf( "Write Buffer is %%%g full: %ld of %ld.\n",
|
||||
100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
|
||||
avail, blio->outputRingBuffer.bufferSize );
|
||||
framesAvailable, blio->outputRingBuffer.bufferSize );
|
||||
*/
|
||||
if( avail == 0 ) {
|
||||
if( framesAvailable == 0 ) {
|
||||
#ifdef PA_MAC_BLIO_MUTEX
|
||||
/*block while full*/
|
||||
ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
|
||||
|
@ -517,16 +535,20 @@ PaError WriteStream( PaStream* stream,
|
|||
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
|
||||
#endif
|
||||
}
|
||||
} while( avail == 0 );
|
||||
} while( framesAvailable == 0 && macStream->state != STOPPING );
|
||||
|
||||
toWrite = MIN( avail, frames * blio->outputSampleSizeActual * blio->outChan );
|
||||
toWrite -= toWrite % blio->outputSampleSizeActual * blio->outChan ;
|
||||
PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, toWrite );
|
||||
cbuf += toWrite;
|
||||
frames -= toWrite / ( blio->outputSampleSizeActual * blio->outChan );
|
||||
if( macStream->state == STOPPING )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
framesToTransfer = MIN( framesAvailable, framesRequested );
|
||||
framesTransferred = PaUtil_WriteRingBuffer( &blio->outputRingBuffer, (void *)cbuf, framesToTransfer );
|
||||
cbuf += framesTransferred * blio->outputSampleSizeActual * blio->outChan;
|
||||
framesRequested -= framesTransferred;
|
||||
|
||||
#ifdef PA_MAC_BLIO_MUTEX
|
||||
if( toWrite == avail ) {
|
||||
if( framesToTransfer == framesAvailable ) {
|
||||
/* we just filled up the buffer, so we need to mark it as filled. */
|
||||
ret = blioSetIsOutputFull( blio, true );
|
||||
if( ret )
|
||||
|
@ -535,6 +557,7 @@ PaError WriteStream( PaStream* stream,
|
|||
so check for that, too, to avoid a race condition. */
|
||||
if( PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer ) ) {
|
||||
blioSetIsOutputFull( blio, false );
|
||||
/* FIXME remove or review this code, does not fix race, ret not set! */
|
||||
if( ret )
|
||||
return ret;
|
||||
}
|
||||
|
@ -542,42 +565,65 @@ PaError WriteStream( PaStream* stream,
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Report either paNoError or paOutputUnderflowed. */
|
||||
/* may also want to report other errors, but this is non-standard. */
|
||||
ret = blio->statusFlags & paOutputUnderflow;
|
||||
if ( macStream->state == STOPPING )
|
||||
{
|
||||
ret = paInternalError;
|
||||
}
|
||||
else if (ret == paNoError )
|
||||
{
|
||||
/* Test for underflow. */
|
||||
ret = blio->statusFlags & paOutputUnderflow;
|
||||
|
||||
/* report underflow only once: */
|
||||
if( ret ) {
|
||||
OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
|
||||
ret = paOutputUnderflowed;
|
||||
/* report underflow only once: */
|
||||
if( ret )
|
||||
{
|
||||
OSAtomicAnd32( (uint32_t)(~paOutputUnderflow), &blio->statusFlags );
|
||||
ret = paOutputUnderflowed;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Wait until the data in the buffer has finished playing.
|
||||
*/
|
||||
void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio )
|
||||
PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate,
|
||||
size_t framesPerBuffer )
|
||||
{
|
||||
PaError result = paNoError;
|
||||
if( blio->outputRingBuffer.buffer ) {
|
||||
long avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
|
||||
while( avail != blio->outputRingBuffer.bufferSize ) {
|
||||
if( avail == 0 )
|
||||
Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
|
||||
avail = PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
|
||||
}
|
||||
}
|
||||
}
|
||||
ring_buffer_size_t framesLeft = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
|
||||
|
||||
/* Calculate when we should give up waiting. To be safe wait for two extra periods. */
|
||||
PaTime now = PaUtil_GetTime();
|
||||
PaTime startTime = now;
|
||||
PaTime timeoutTime = startTime + (framesLeft + (2 * framesPerBuffer)) / sampleRate;
|
||||
|
||||
long msecPerBuffer = 1 + (long)( 1000.0 * framesPerBuffer / sampleRate);
|
||||
while( framesLeft > 0 && now < timeoutTime ) {
|
||||
VDBUG(( "waitUntilBlioWriteBufferIsFlushed: framesLeft = %d, framesPerBuffer = %ld\n",
|
||||
framesLeft, framesPerBuffer ));
|
||||
Pa_Sleep( msecPerBuffer );
|
||||
framesLeft = PaUtil_GetRingBufferReadAvailable( &blio->outputRingBuffer );
|
||||
now = PaUtil_GetTime();
|
||||
}
|
||||
|
||||
if( framesLeft > 0 )
|
||||
{
|
||||
VDBUG(( "waitUntilBlioWriteBufferIsFlushed: TIMED OUT - framesLeft = %d\n", framesLeft ));
|
||||
result = paTimedOut;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
signed long GetStreamReadAvailable( PaStream* stream )
|
||||
{
|
||||
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
|
||||
VVDBUG(("GetStreamReadAvailable()\n"));
|
||||
|
||||
return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer )
|
||||
/ ( blio->inputSampleSizeActual * blio->inChan );
|
||||
return PaUtil_GetRingBufferReadAvailable( &blio->inputRingBuffer );
|
||||
}
|
||||
|
||||
|
||||
|
@ -586,7 +632,6 @@ signed long GetStreamWriteAvailable( PaStream* stream )
|
|||
PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
|
||||
VVDBUG(("GetStreamWriteAvailable()\n"));
|
||||
|
||||
return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer )
|
||||
/ ( blio->outputSampleSizeActual * blio->outChan );
|
||||
return PaUtil_GetRingBufferWriteAvailable( &blio->outputRingBuffer );
|
||||
}
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#include "pa_mac_core_utilities.h"
|
||||
|
||||
/*
|
||||
* Number of miliseconds to busy wait whil waiting for data in blocking calls.
|
||||
* Number of milliseconds to busy wait while waiting for data in blocking calls.
|
||||
*/
|
||||
#define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5)
|
||||
/*
|
||||
|
@ -79,7 +79,7 @@
|
|||
typedef struct {
|
||||
PaUtilRingBuffer inputRingBuffer;
|
||||
PaUtilRingBuffer outputRingBuffer;
|
||||
size_t ringBufferFrames;
|
||||
ring_buffer_size_t ringBufferFrames;
|
||||
PaSampleFormat inputSampleFormat;
|
||||
size_t inputSampleSizeActual;
|
||||
size_t inputSampleSizePow2;
|
||||
|
@ -87,8 +87,6 @@ typedef struct {
|
|||
size_t outputSampleSizeActual;
|
||||
size_t outputSampleSizePow2;
|
||||
|
||||
size_t framesPerBuffer;
|
||||
|
||||
int inChan;
|
||||
int outChan;
|
||||
|
||||
|
@ -117,8 +115,7 @@ PaError initializeBlioRingBuffers(
|
|||
PaMacBlio *blio,
|
||||
PaSampleFormat inputSampleFormat,
|
||||
PaSampleFormat outputSampleFormat,
|
||||
size_t framesPerBuffer,
|
||||
long ringBufferSize,
|
||||
long ringBufferSizeInFrames,
|
||||
int inChan,
|
||||
int outChan );
|
||||
PaError destroyBlioRingBuffers( PaMacBlio *blio );
|
||||
|
@ -131,6 +128,7 @@ int BlioCallback(
|
|||
PaStreamCallbackFlags statusFlags,
|
||||
void *userData );
|
||||
|
||||
void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio );
|
||||
PaError waitUntilBlioWriteBufferIsEmpty( PaMacBlio *blio, double sampleRate,
|
||||
size_t framesPerBuffer );
|
||||
|
||||
#endif /*PA_MAC_CORE_BLOCKING_H_*/
|
||||
|
|
|
@ -120,7 +120,11 @@ typedef struct PaMacCoreDeviceProperties
|
|||
UInt32 bufferFrameSize;
|
||||
// UInt32 streamLatency; // Seems to be the same as deviceLatency!?
|
||||
UInt32 deviceLatency;
|
||||
/* Current device sample rate. May change! */
|
||||
/* Current device sample rate. May change!
|
||||
These are initialized to the nominal device sample rate,
|
||||
and updated with the actual sample rate, when/where available.
|
||||
Note that these are the *device* sample rates, prior to any required
|
||||
SR conversion. */
|
||||
Float64 sampleRate;
|
||||
Float64 samplePeriod; // reciprocal
|
||||
}
|
||||
|
@ -166,10 +170,6 @@ typedef struct PaMacCoreStream
|
|||
ACTIVE = 3 /* The stream is active and running. */
|
||||
} state;
|
||||
double sampleRate;
|
||||
//these may be different from the stream sample rate due to SR conversion:
|
||||
double outDeviceSampleRate;
|
||||
double inDeviceSampleRate;
|
||||
|
||||
PaMacCoreDeviceProperties inputProperties;
|
||||
PaMacCoreDeviceProperties outputProperties;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_mac_core_old.c 1083 2006-08-23 07:30:49Z rossb $
|
||||
* $Id$
|
||||
* pa_mac_core.c
|
||||
* Implementation of PortAudio for Mac OS X CoreAudio
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_ds.c 1779 2011-11-10 14:51:15Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library DirectSound implementation
|
||||
*
|
||||
* Authors: Phil Burk, Robert Marsanyi & Ross Bencina
|
||||
|
@ -152,6 +152,13 @@ PA_THREAD_FUNC ProcessingThreadProc( void *pArg );
|
|||
|
||||
#define PA_DS_WIN_WDM_DEFAULT_LATENCY_ (.120)
|
||||
|
||||
/* we allow the polling period to range between 1 and 100ms.
|
||||
prior to August 2011 we limited the minimum polling period to 10ms.
|
||||
*/
|
||||
#define PA_DS_MINIMUM_POLLING_PERIOD_SECONDS (0.001) /* 1ms */
|
||||
#define PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS (0.100) /* 100ms */
|
||||
#define PA_DS_POLLING_JITTER_SECONDS (0.001) /* 1ms */
|
||||
|
||||
#define SECONDS_PER_MSEC (0.001)
|
||||
#define MSECS_PER_SECOND (1000)
|
||||
|
||||
|
@ -201,9 +208,9 @@ static signed long GetStreamWriteAvailable( PaStream* stream );
|
|||
PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" )
|
||||
|
||||
/************************************************* DX Prototypes **********/
|
||||
static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
|
||||
LPCTSTR lpszDesc,
|
||||
LPCTSTR lpszDrvName,
|
||||
static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
||||
LPCWSTR lpszDesc,
|
||||
LPCWSTR lpszDrvName,
|
||||
LPVOID lpContext );
|
||||
|
||||
/************************************************************************************/
|
||||
|
@ -311,30 +318,43 @@ typedef struct PaWinDsStream
|
|||
*/
|
||||
static double PaWinDS_GetMinSystemLatencySeconds( void )
|
||||
{
|
||||
/*
|
||||
NOTE: GetVersionEx() is deprecated as of Windows 8.1 and can not be used to reliably detect
|
||||
versions of Windows higher than Windows 8 (due to manifest requirements for reporting higher versions).
|
||||
Microsoft recommends switching to VerifyVersionInfo (available on Win 2k and later), however GetVersionEx
|
||||
is is faster, for now we just disable the deprecation warning.
|
||||
See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
|
||||
See: http://www.codeproject.com/Articles/678606/Part-Overcoming-Windows-s-deprecation-of-GetVe
|
||||
*/
|
||||
#pragma warning (disable : 4996) /* use of GetVersionEx */
|
||||
|
||||
double minLatencySeconds;
|
||||
/* Set minimal latency based on whether NT or other OS.
|
||||
* NT has higher latency.
|
||||
*/
|
||||
|
||||
OSVERSIONINFO osvi;
|
||||
osvi.dwOSVersionInfoSize = sizeof( osvi );
|
||||
GetVersionEx( &osvi );
|
||||
osvi.dwOSVersionInfoSize = sizeof( osvi );
|
||||
GetVersionEx( &osvi );
|
||||
DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));
|
||||
DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));
|
||||
DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));
|
||||
/* Check for NT */
|
||||
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
|
||||
{
|
||||
minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_;
|
||||
}
|
||||
else if(osvi.dwMajorVersion >= 5)
|
||||
{
|
||||
minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_;
|
||||
}
|
||||
else
|
||||
{
|
||||
minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_;
|
||||
}
|
||||
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
|
||||
{
|
||||
minLatencySeconds = PA_DS_WIN_NT_DEFAULT_LATENCY_;
|
||||
}
|
||||
else if(osvi.dwMajorVersion >= 5)
|
||||
{
|
||||
minLatencySeconds = PA_DS_WIN_WDM_DEFAULT_LATENCY_;
|
||||
}
|
||||
else
|
||||
{
|
||||
minLatencySeconds = PA_DS_WIN_9X_DEFAULT_LATENCY_;
|
||||
}
|
||||
return minLatencySeconds;
|
||||
|
||||
#pragma warning (default : 4996)
|
||||
}
|
||||
|
||||
|
||||
|
@ -360,7 +380,7 @@ static double PaWinDs_GetMinLatencySeconds( double sampleRate )
|
|||
double minLatencySeconds = 0;
|
||||
|
||||
/* Let user determine minimal latency by setting environment variable. */
|
||||
hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );
|
||||
hresult = GetEnvironmentVariableA( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );
|
||||
if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
|
||||
{
|
||||
minLatencySeconds = atoi( envbuf ) * SECONDS_PER_MSEC;
|
||||
|
@ -378,20 +398,35 @@ static double PaWinDs_GetMinLatencySeconds( double sampleRate )
|
|||
|
||||
|
||||
/************************************************************************************
|
||||
** Duplicate the input string using the allocations allocator.
|
||||
** Duplicate and convert the input string using the group allocations allocator.
|
||||
** A NULL string is converted to a zero length string.
|
||||
** If memory cannot be allocated, NULL is returned.
|
||||
**/
|
||||
static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src )
|
||||
static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const wchar_t* src )
|
||||
{
|
||||
char *result = 0;
|
||||
|
||||
if( src != NULL )
|
||||
{
|
||||
size_t len = strlen(src);
|
||||
#if !defined(_UNICODE) && !defined(UNICODE)
|
||||
size_t len = WideCharToMultiByte(CP_ACP, 0, src, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) );
|
||||
if( result )
|
||||
memcpy( (void *) result, src, len+1 );
|
||||
if( result ) {
|
||||
if (WideCharToMultiByte(CP_ACP, 0, src, -1, result, (int)len, NULL, NULL) == 0) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
size_t len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
|
||||
|
||||
result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) );
|
||||
if( result ) {
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, src, -1, result, (int)len, NULL, NULL) == 0) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -473,7 +508,7 @@ static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidV
|
|||
else
|
||||
{
|
||||
newItems[i].lpGUID = &newItems[i].guid;
|
||||
memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );;
|
||||
memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );
|
||||
}
|
||||
newItems[i].pnpInterface = guidVector->items[i].pnpInterface;
|
||||
}
|
||||
|
@ -506,9 +541,9 @@ static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *gu
|
|||
/************************************************************************************
|
||||
** Collect preliminary device information during DirectSound enumeration
|
||||
*/
|
||||
static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
|
||||
LPCTSTR lpszDesc,
|
||||
LPCTSTR lpszDrvName,
|
||||
static BOOL CALLBACK CollectGUIDsProcW(LPGUID lpGUID,
|
||||
LPCWSTR lpszDesc,
|
||||
LPCWSTR lpszDrvName,
|
||||
LPVOID lpContext )
|
||||
{
|
||||
DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext;
|
||||
|
@ -574,29 +609,38 @@ static BOOL CALLBACK KsPropertySetEnumerateCallback( PDSPROPERTY_DIRECTSOUNDDEVI
|
|||
int i;
|
||||
DSDeviceNamesAndGUIDs *deviceNamesAndGUIDs = (DSDeviceNamesAndGUIDs*)context;
|
||||
|
||||
if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER )
|
||||
/*
|
||||
Apparently data->Interface can be NULL in some cases.
|
||||
Possibly virtual devices without hardware.
|
||||
So we check for NULLs now. See mailing list message November 10, 2012:
|
||||
"[Portaudio] portaudio initialization crash in KsPropertySetEnumerateCallback(pa_win_ds.c)"
|
||||
*/
|
||||
if( data->Interface )
|
||||
{
|
||||
for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i )
|
||||
if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER )
|
||||
{
|
||||
if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID
|
||||
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
||||
for( i=0; i < deviceNamesAndGUIDs->outputNamesAndGUIDs.count; ++i )
|
||||
{
|
||||
deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface =
|
||||
if( deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID
|
||||
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
||||
{
|
||||
deviceNamesAndGUIDs->outputNamesAndGUIDs.items[i].pnpInterface =
|
||||
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE )
|
||||
{
|
||||
for( i=0; i < deviceNamesAndGUIDs->inputNamesAndGUIDs.count; ++i )
|
||||
else if( data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE )
|
||||
{
|
||||
if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID
|
||||
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
||||
for( i=0; i < deviceNamesAndGUIDs->inputNamesAndGUIDs.count; ++i )
|
||||
{
|
||||
deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface =
|
||||
if( deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID
|
||||
&& memcmp( &data->DeviceId, deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].lpGUID, sizeof(GUID) ) == 0 )
|
||||
{
|
||||
deviceNamesAndGUIDs->inputNamesAndGUIDs.items[i].pnpInterface =
|
||||
(char*)DuplicateWCharString( deviceNamesAndGUIDs->winDsHostApi->allocations, data->Interface );
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -922,7 +966,7 @@ static PaError AddOutputDeviceInfoFromDirectSound(
|
|||
}
|
||||
else
|
||||
{
|
||||
deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
|
||||
deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
|
||||
}
|
||||
}
|
||||
else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )
|
||||
|
@ -1160,6 +1204,8 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
|||
goto error;
|
||||
}
|
||||
|
||||
memset( winDsHostApi, 0, sizeof(PaWinDsHostApiRepresentation) ); /* ensure all fields are zeroed. especially winDsHostApi->allocations */
|
||||
|
||||
result = PaWinUtil_CoInitialize( paDirectSound, &winDsHostApi->comInitializationResult );
|
||||
if( result != paNoError )
|
||||
{
|
||||
|
@ -1193,9 +1239,9 @@ PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInde
|
|||
if( result != paNoError )
|
||||
goto error;
|
||||
|
||||
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||
paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW( (LPDSENUMCALLBACKW)CollectGUIDsProcW, (void *)&deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||
|
||||
paWinDsDSoundEntryPoints.DirectSoundEnumerateA( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs );
|
||||
paWinDsDSoundEntryPoints.DirectSoundEnumerateW( (LPDSENUMCALLBACKW)CollectGUIDsProcW, (void *)&deviceNamesAndGUIDs.outputNamesAndGUIDs );
|
||||
|
||||
if( deviceNamesAndGUIDs.inputNamesAndGUIDs.enumerationError != paNoError )
|
||||
{
|
||||
|
@ -1299,7 +1345,7 @@ error:
|
|||
TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.inputNamesAndGUIDs );
|
||||
TerminateDSDeviceNameAndGUIDVector( &deviceNamesAndGUIDs.outputNamesAndGUIDs );
|
||||
|
||||
Terminate( winDsHostApi );
|
||||
Terminate( (struct PaUtilHostApiRepresentation *)winDsHostApi );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -1329,16 +1375,23 @@ static PaError ValidateWinDirectSoundSpecificStreamInfo(
|
|||
const PaStreamParameters *streamParameters,
|
||||
const PaWinDirectSoundStreamInfo *streamInfo )
|
||||
{
|
||||
if( streamInfo )
|
||||
{
|
||||
if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo )
|
||||
|| streamInfo->version != 2 )
|
||||
{
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
}
|
||||
}
|
||||
if( streamInfo )
|
||||
{
|
||||
if( streamInfo->size != sizeof( PaWinDirectSoundStreamInfo )
|
||||
|| streamInfo->version != 2 )
|
||||
{
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
if( streamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
|
||||
{
|
||||
if( streamInfo->framesPerBuffer <= 0 )
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
/***********************************************************************************/
|
||||
|
@ -1375,8 +1428,8 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
/* validate inputStreamInfo */
|
||||
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1404,8 +1457,8 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
/* validate outputStreamInfo */
|
||||
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1541,7 +1594,13 @@ static HRESULT InitFullDuplexInputOutputBuffers( PaWinDsStream *stream,
|
|||
#endif /* PAWIN_USE_DIRECTSOUNDFULLDUPLEXCREATE */
|
||||
|
||||
|
||||
static HRESULT InitInputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device, PaSampleFormat sampleFormat, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer, PaWinWaveFormatChannelMask channelMask )
|
||||
static HRESULT InitInputBuffer( PaWinDsStream *stream,
|
||||
PaWinDsDeviceInfo *device,
|
||||
PaSampleFormat sampleFormat,
|
||||
unsigned long nFrameRate,
|
||||
WORD nChannels,
|
||||
int bytesPerBuffer,
|
||||
PaWinWaveFormatChannelMask channelMask )
|
||||
{
|
||||
DSCBUFFERDESC captureDesc;
|
||||
PaWinWaveFormat waveFormat;
|
||||
|
@ -1582,7 +1641,10 @@ static HRESULT InitInputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device
|
|||
}
|
||||
|
||||
|
||||
static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device, PaSampleFormat sampleFormat, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer, PaWinWaveFormatChannelMask channelMask )
|
||||
static HRESULT InitOutputBuffer( PaWinDsStream *stream, PaWinDsDeviceInfo *device,
|
||||
PaSampleFormat sampleFormat, unsigned long nFrameRate,
|
||||
WORD nChannels, int bytesPerBuffer,
|
||||
PaWinWaveFormatChannelMask channelMask )
|
||||
{
|
||||
HRESULT result;
|
||||
HWND hWnd;
|
||||
|
@ -1680,12 +1742,9 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
|||
unsigned long suggestedOutputLatencyFrames,
|
||||
double sampleRate, unsigned long userFramesPerBuffer )
|
||||
{
|
||||
/* we allow the polling period to range between 1 and 100ms.
|
||||
prior to August 2011 we limited the minimum polling period to 10ms.
|
||||
*/
|
||||
unsigned long minimumPollingPeriodFrames = sampleRate / 1000; /* 1ms */
|
||||
unsigned long maximumPollingPeriodFrames = sampleRate / 10; /* 100ms */
|
||||
unsigned long pollingJitterFrames = sampleRate / 1000; /* 1ms */
|
||||
unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS);
|
||||
|
||||
if( userFramesPerBuffer == paFramesPerBufferUnspecified )
|
||||
{
|
||||
|
@ -1747,6 +1806,23 @@ static void CalculateBufferSettings( unsigned long *hostBufferSizeFrames,
|
|||
}
|
||||
|
||||
|
||||
static void CalculatePollingPeriodFrames( unsigned long hostBufferSizeFrames,
|
||||
unsigned long *pollingPeriodFrames,
|
||||
double sampleRate, unsigned long userFramesPerBuffer )
|
||||
{
|
||||
unsigned long minimumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MINIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long maximumPollingPeriodFrames = (unsigned long)(sampleRate * PA_DS_MAXIMUM_POLLING_PERIOD_SECONDS);
|
||||
unsigned long pollingJitterFrames = (unsigned long)(sampleRate * PA_DS_POLLING_JITTER_SECONDS);
|
||||
|
||||
*pollingPeriodFrames = max( max(1, userFramesPerBuffer / 4), hostBufferSizeFrames / 16 );
|
||||
|
||||
if( *pollingPeriodFrames > maximumPollingPeriodFrames )
|
||||
{
|
||||
*pollingPeriodFrames = maximumPollingPeriodFrames;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void SetStreamInfoLatencies( PaWinDsStream *stream,
|
||||
unsigned long userFramesPerBuffer,
|
||||
unsigned long pollingPeriodFrames,
|
||||
|
@ -1808,6 +1884,8 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
int inputChannelCount, outputChannelCount;
|
||||
PaSampleFormat inputSampleFormat, outputSampleFormat;
|
||||
PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
|
||||
int userRequestedHostInputBufferSizeFrames = 0;
|
||||
int userRequestedHostOutputBufferSizeFrames = 0;
|
||||
unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames;
|
||||
PaWinDirectSoundStreamInfo *inputStreamInfo, *outputStreamInfo;
|
||||
PaWinWaveFormatChannelMask inputChannelMask, outputChannelMask;
|
||||
|
@ -1837,8 +1915,11 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
/* validate hostApiSpecificStreamInfo */
|
||||
inputStreamInfo = (PaWinDirectSoundStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( inputParameters, inputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
|
||||
userRequestedHostInputBufferSizeFrames = inputStreamInfo->framesPerBuffer;
|
||||
|
||||
if( inputStreamInfo && inputStreamInfo->flags & paWinDirectSoundUseChannelMask )
|
||||
inputChannelMask = inputStreamInfo->channelMask;
|
||||
|
@ -1848,7 +1929,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
else
|
||||
{
|
||||
inputChannelCount = 0;
|
||||
inputSampleFormat = 0;
|
||||
inputSampleFormat = 0;
|
||||
suggestedInputLatencyFrames = 0;
|
||||
}
|
||||
|
||||
|
@ -1874,8 +1955,11 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
/* validate hostApiSpecificStreamInfo */
|
||||
outputStreamInfo = (PaWinDirectSoundStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
result = ValidateWinDirectSoundSpecificStreamInfo( outputParameters, outputStreamInfo );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseLowLevelLatencyParameters )
|
||||
userRequestedHostOutputBufferSizeFrames = outputStreamInfo->framesPerBuffer;
|
||||
|
||||
if( outputStreamInfo && outputStreamInfo->flags & paWinDirectSoundUseChannelMask )
|
||||
outputChannelMask = outputStreamInfo->channelMask;
|
||||
|
@ -1885,10 +1969,20 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
else
|
||||
{
|
||||
outputChannelCount = 0;
|
||||
outputSampleFormat = 0;
|
||||
outputSampleFormat = 0;
|
||||
suggestedOutputLatencyFrames = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
If low level host buffer size is specified for both input and output
|
||||
the current code requires the sizes to match.
|
||||
*/
|
||||
|
||||
if( (userRequestedHostInputBufferSizeFrames > 0 && userRequestedHostOutputBufferSizeFrames > 0)
|
||||
&& userRequestedHostInputBufferSizeFrames != userRequestedHostOutputBufferSizeFrames )
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
IMPLEMENT ME:
|
||||
|
@ -1956,10 +2050,10 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
hostInputSampleFormat =
|
||||
PaUtil_SelectClosestAvailableFormat( nativeInputFormats, inputParameters->sampleFormat );
|
||||
}
|
||||
else
|
||||
{
|
||||
hostInputSampleFormat = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hostInputSampleFormat = 0;
|
||||
}
|
||||
|
||||
if( outputParameters )
|
||||
{
|
||||
|
@ -1971,9 +2065,9 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
PaUtil_SelectClosestAvailableFormat( nativeOutputFormats, outputParameters->sampleFormat );
|
||||
}
|
||||
else
|
||||
{
|
||||
hostOutputSampleFormat = 0;
|
||||
}
|
||||
{
|
||||
hostOutputSampleFormat = 0;
|
||||
}
|
||||
|
||||
result = PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
|
||||
inputChannelCount, inputSampleFormat, hostInputSampleFormat,
|
||||
|
@ -2016,7 +2110,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
#endif
|
||||
|
||||
#ifndef PA_WIN_DS_USE_WMME_TIMER
|
||||
stream->processingThreadCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL );
|
||||
stream->processingThreadCompleted = CreateEvent( NULL, /* bManualReset = */ TRUE, /* bInitialState = */ FALSE, NULL );
|
||||
if( stream->processingThreadCompleted == NULL )
|
||||
{
|
||||
result = paUnanticipatedHostError;
|
||||
|
@ -2027,14 +2121,34 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
/* set up i/o parameters */
|
||||
|
||||
CalculateBufferSettings( &stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
||||
/* isFullDuplex = */ (inputParameters && outputParameters),
|
||||
suggestedInputLatencyFrames,
|
||||
suggestedOutputLatencyFrames,
|
||||
sampleRate, framesPerBuffer );
|
||||
if( userRequestedHostInputBufferSizeFrames > 0 || userRequestedHostOutputBufferSizeFrames > 0 )
|
||||
{
|
||||
/* use low level parameters */
|
||||
|
||||
/* since we use the same host buffer size for input and output
|
||||
we choose the highest user specified value.
|
||||
*/
|
||||
stream->hostBufferSizeFrames = max( userRequestedHostInputBufferSizeFrames, userRequestedHostOutputBufferSizeFrames );
|
||||
|
||||
CalculatePollingPeriodFrames(
|
||||
stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
||||
sampleRate, framesPerBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
CalculateBufferSettings( &stream->hostBufferSizeFrames, &pollingPeriodFrames,
|
||||
/* isFullDuplex = */ (inputParameters && outputParameters),
|
||||
suggestedInputLatencyFrames,
|
||||
suggestedOutputLatencyFrames,
|
||||
sampleRate, framesPerBuffer );
|
||||
}
|
||||
|
||||
stream->pollingPeriodSeconds = pollingPeriodFrames / sampleRate;
|
||||
|
||||
DBUG(("DirectSound host buffer size frames: %d, polling period seconds: %f, @ sr: %f\n",
|
||||
stream->hostBufferSizeFrames, stream->pollingPeriodSeconds, sampleRate ));
|
||||
|
||||
|
||||
/* ------------------ OUTPUT */
|
||||
if( outputParameters )
|
||||
{
|
||||
|
@ -2396,6 +2510,8 @@ static int TimeSlice( PaWinDsStream *stream )
|
|||
framesToXfer = numOutFramesReady = bytesEmpty / stream->outputFrameSizeBytes;
|
||||
|
||||
/* Check for underflow */
|
||||
/* FIXME QueryOutputSpace should not adjust underflow count as a side effect.
|
||||
A query function should be a const operator on the stream and return a flag on underflow. */
|
||||
if( stream->outputUnderflowCount != previousUnderflowCount )
|
||||
stream->callbackFlags |= paOutputUnderflow;
|
||||
|
||||
|
@ -2460,8 +2576,8 @@ static int TimeSlice( PaWinDsStream *stream )
|
|||
if( stream->bufferProcessor.outputChannelCount > 0 )
|
||||
{
|
||||
/*
|
||||
We don't currently add outputLatency here because it appears to produce worse
|
||||
results than non adding it. Need to do more testing to verify this.
|
||||
We don't currently add outputLatency here because it appears to produce worse
|
||||
results than not adding it. Need to do more testing to verify this.
|
||||
*/
|
||||
/* timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency; */
|
||||
timeInfo.outputBufferDacTime = timeInfo.currentTime;
|
||||
|
@ -2649,12 +2765,10 @@ static void CALLBACK WaitableTimerAPCProc(
|
|||
PA_THREAD_FUNC ProcessingThreadProc( void *pArg )
|
||||
{
|
||||
PaWinDsStream *stream = (PaWinDsStream *)pArg;
|
||||
MMRESULT mmResult;
|
||||
HANDLE hWaitableTimer;
|
||||
LARGE_INTEGER dueTime;
|
||||
int timerPeriodMs;
|
||||
|
||||
timerPeriodMs = stream->pollingPeriodSeconds * MSECS_PER_SECOND;
|
||||
timerPeriodMs = (int)(stream->pollingPeriodSeconds * MSECS_PER_SECOND);
|
||||
if( timerPeriodMs < 1 )
|
||||
timerPeriodMs = 1;
|
||||
|
||||
|
@ -2712,7 +2826,7 @@ static PaError CloseStream( PaStream* s )
|
|||
#endif
|
||||
|
||||
#ifndef PA_WIN_DS_USE_WMME_TIMER
|
||||
CloseHandle( stream->processingThreadCompleted );
|
||||
CloseHandle( stream->processingThreadCompleted );
|
||||
#endif
|
||||
|
||||
// Cleanup the sound buffers
|
||||
|
@ -2810,7 +2924,7 @@ static PaError StartStream( PaStream *s )
|
|||
ResetEvent( stream->processingCompleted );
|
||||
|
||||
#ifndef PA_WIN_DS_USE_WMME_TIMER
|
||||
ResetEvent( stream->processingThreadCompleted );
|
||||
ResetEvent( stream->processingThreadCompleted );
|
||||
#endif
|
||||
|
||||
if( stream->bufferProcessor.inputChannelCount > 0 )
|
||||
|
@ -2878,7 +2992,7 @@ static PaError StartStream( PaStream *s )
|
|||
if( stream->streamRepresentation.streamCallback )
|
||||
{
|
||||
TIMECAPS timecaps;
|
||||
int timerPeriodMs = stream->pollingPeriodSeconds * MSECS_PER_SECOND;
|
||||
int timerPeriodMs = (int)(stream->pollingPeriodSeconds * MSECS_PER_SECOND);
|
||||
if( timerPeriodMs < 1 )
|
||||
timerPeriodMs = 1;
|
||||
|
||||
|
@ -2889,10 +3003,10 @@ static PaError StartStream( PaStream *s )
|
|||
we're using an MM timer callback via timeSetEvent or not.
|
||||
*/
|
||||
assert( stream->systemTimerResolutionPeriodMs == 0 );
|
||||
if( timeGetDevCaps( &timecaps, sizeof(TIMECAPS) == MMSYSERR_NOERROR && timecaps.wPeriodMin > 0 ) )
|
||||
if( timeGetDevCaps( &timecaps, sizeof(TIMECAPS) ) == MMSYSERR_NOERROR && timecaps.wPeriodMin > 0 )
|
||||
{
|
||||
/* aim for resolution 4 times higher than polling rate */
|
||||
stream->systemTimerResolutionPeriodMs = (stream->pollingPeriodSeconds * MSECS_PER_SECOND) / 4;
|
||||
stream->systemTimerResolutionPeriodMs = (UINT)((stream->pollingPeriodSeconds * MSECS_PER_SECOND) * .25);
|
||||
if( stream->systemTimerResolutionPeriodMs < timecaps.wPeriodMin )
|
||||
stream->systemTimerResolutionPeriodMs = timecaps.wPeriodMin;
|
||||
if( stream->systemTimerResolutionPeriodMs > timecaps.wPeriodMax )
|
||||
|
@ -2920,9 +3034,9 @@ static PaError StartStream( PaStream *s )
|
|||
goto error;
|
||||
}
|
||||
#else
|
||||
/* Create processing thread which calls TimerCallback */
|
||||
/* Create processing thread which calls TimerCallback */
|
||||
|
||||
stream->processingThread = CREATE_THREAD( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId );
|
||||
stream->processingThread = CREATE_THREAD( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId );
|
||||
if( !stream->processingThread )
|
||||
{
|
||||
result = paUnanticipatedHostError;
|
||||
|
@ -2992,8 +3106,8 @@ static PaError StopStream( PaStream *s )
|
|||
#else
|
||||
if( stream->processingThread )
|
||||
{
|
||||
if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT )
|
||||
return paUnanticipatedHostError;
|
||||
if( WaitForSingleObject( stream->processingThreadCompleted, 30*100 ) == WAIT_TIMEOUT )
|
||||
return paUnanticipatedHostError;
|
||||
|
||||
#ifdef CLOSE_THREAD_HANDLE
|
||||
CloseHandle( stream->processingThread ); /* Delete thread. */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_jack.c 1668 2011-05-02 17:07:11Z rossb $
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Latest Version at: http://www.portaudio.com
|
||||
* JACK Implementation by Joshua Haberman
|
||||
|
@ -232,6 +232,10 @@ typedef struct PaJackStream
|
|||
}
|
||||
PaJackStream;
|
||||
|
||||
/* In calls to jack_get_ports() this filter expression is used instead of ""
|
||||
* to prevent any other types (eg Midi ports etc) being listed */
|
||||
#define JACK_PORT_TYPE_FILTER "audio"
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
|
@ -492,7 +496,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
|
|||
* according to the client_name:port_name convention (which is
|
||||
* enforced by jackd)
|
||||
* A: If jack_get_ports returns NULL, there's nothing for us to do */
|
||||
UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", "", 0 )) && jack_ports[0], paNoError );
|
||||
UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", JACK_PORT_TYPE_FILTER, 0 )) && jack_ports[0], paNoError );
|
||||
/* Find number of ports */
|
||||
while( jack_ports[numPorts] )
|
||||
++numPorts;
|
||||
|
@ -583,7 +587,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
|
|||
|
||||
/* ... what are your output ports (that we could input from)? */
|
||||
clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
|
||||
NULL, JackPortIsOutput);
|
||||
JACK_PORT_TYPE_FILTER, JackPortIsOutput);
|
||||
curDevInfo->maxInputChannels = 0;
|
||||
curDevInfo->defaultLowInputLatency = 0.;
|
||||
curDevInfo->defaultHighInputLatency = 0.;
|
||||
|
@ -604,7 +608,7 @@ static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
|
|||
|
||||
/* ... what are your input ports (that we could output to)? */
|
||||
clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
|
||||
NULL, JackPortIsInput);
|
||||
JACK_PORT_TYPE_FILTER, JackPortIsInput);
|
||||
curDevInfo->maxOutputChannels = 0;
|
||||
curDevInfo->defaultLowOutputLatency = 0.;
|
||||
curDevInfo->defaultHighOutputLatency = 0.;
|
||||
|
@ -1235,7 +1239,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
/* Get output ports of our capture device */
|
||||
snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name );
|
||||
UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
|
||||
NULL, JackPortIsOutput ), paUnanticipatedHostError );
|
||||
JACK_PORT_TYPE_FILTER, JackPortIsOutput ), paUnanticipatedHostError );
|
||||
for( i = 0; i < inputChannelCount && jack_ports[i]; i++ )
|
||||
{
|
||||
if( (stream->remote_output_ports[i] = jack_port_by_name(
|
||||
|
@ -1259,7 +1263,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
/* Get input ports of our playback device */
|
||||
snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name );
|
||||
UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
|
||||
NULL, JackPortIsInput ), paUnanticipatedHostError );
|
||||
JACK_PORT_TYPE_FILTER, JackPortIsInput ), paUnanticipatedHostError );
|
||||
for( i = 0; i < outputChannelCount && jack_ports[i]; i++ )
|
||||
{
|
||||
if( (stream->remote_input_ports[i] = jack_port_by_name(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_unix_oss.c 1668 2011-05-02 17:07:11Z rossb $
|
||||
* $Id$
|
||||
* PortAudio Portable Real-Time Audio Library
|
||||
* Latest Version at: http://www.portaudio.com
|
||||
* OSS implementation by:
|
||||
|
@ -318,6 +318,13 @@ error:
|
|||
return result;
|
||||
}
|
||||
|
||||
static int CalcHigherLogTwo( int n )
|
||||
{
|
||||
int log2 = 0;
|
||||
while( (1<<log2) < n ) log2++;
|
||||
return log2;
|
||||
}
|
||||
|
||||
static PaError QueryDirection( const char *deviceName, StreamMode mode, double *defaultSampleRate, int *maxChannelCount,
|
||||
double *defaultLowLatency, double *defaultHighLatency )
|
||||
{
|
||||
|
@ -327,6 +334,8 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
|
|||
int devHandle = -1;
|
||||
int sr;
|
||||
*maxChannelCount = 0; /* Default value in case this fails */
|
||||
int temp, frgmt;
|
||||
unsigned long fragFrames;
|
||||
|
||||
if ( (devHandle = open( deviceName, (mode == StreamMode_In ? O_RDONLY : O_WRONLY) | O_NONBLOCK )) < 0 )
|
||||
{
|
||||
|
@ -354,7 +363,7 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
|
|||
maxNumChannels = 0;
|
||||
for( numChannels = 1; numChannels <= 16; numChannels++ )
|
||||
{
|
||||
int temp = numChannels;
|
||||
temp = numChannels;
|
||||
if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 )
|
||||
{
|
||||
busy = EAGAIN == errno || EBUSY == errno;
|
||||
|
@ -401,8 +410,8 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
|
|||
* to a supported number of channels. SG20011005 */
|
||||
{
|
||||
/* use most reasonable default value */
|
||||
int temp = PA_MIN( maxNumChannels, 2 );
|
||||
ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError );
|
||||
numChannels = PA_MIN( maxNumChannels, 2 );
|
||||
ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &numChannels ), paUnanticipatedHostError );
|
||||
}
|
||||
|
||||
/* Get supported sample rate closest to 44100 Hz */
|
||||
|
@ -415,9 +424,21 @@ static PaError QueryDirection( const char *deviceName, StreamMode mode, double *
|
|||
}
|
||||
|
||||
*maxChannelCount = maxNumChannels;
|
||||
/* TODO */
|
||||
*defaultLowLatency = 512. / *defaultSampleRate;
|
||||
*defaultHighLatency = 2048. / *defaultSampleRate;
|
||||
|
||||
/* Attempt to set low latency with 4 frags-per-buffer, 128 frames-per-frag (total buffer 512 frames)
|
||||
* since the ioctl sets bytes, multiply by numChannels, and base on 2 bytes-per-sample, */
|
||||
fragFrames = 128;
|
||||
frgmt = (4 << 16) + (CalcHigherLogTwo( fragFrames * numChannels * 2 ) & 0xffff);
|
||||
ENSURE_( ioctl( devHandle, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError );
|
||||
|
||||
/* Use the value set by the ioctl to give the latency achieved */
|
||||
fragFrames = pow( 2, frgmt & 0xffff ) / (numChannels * 2);
|
||||
*defaultLowLatency = ((frgmt >> 16) - 1) * fragFrames / *defaultSampleRate;
|
||||
|
||||
/* Cannot now try setting a high latency (device would need closing and opening again). Make
|
||||
* high-latency 4 times the low unless the fragFrames are significantly more than requested 128 */
|
||||
temp = (fragFrames < 256) ? 4 : (fragFrames < 512) ? 2 : 1;
|
||||
*defaultHighLatency = temp * *defaultLowLatency;
|
||||
|
||||
error:
|
||||
if( devHandle >= 0 )
|
||||
|
@ -962,13 +983,6 @@ static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *comp
|
|||
return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs;
|
||||
}
|
||||
|
||||
static int CalcHigherLogTwo( int n )
|
||||
{
|
||||
int log2 = 0;
|
||||
while( (1<<log2) < n ) log2++;
|
||||
return log2;
|
||||
}
|
||||
|
||||
/** Configure stream component device parameters.
|
||||
*/
|
||||
static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long
|
||||
|
@ -995,8 +1009,9 @@ static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component,
|
|||
*/
|
||||
if( framesPerBuffer == paFramesPerBufferUnspecified )
|
||||
{
|
||||
bufSz = (unsigned long)(component->latency * sampleRate);
|
||||
fragSz = bufSz / 4;
|
||||
/* Aim for 4 fragments in the complete buffer; the latency comes from 3 of these */
|
||||
fragSz = (unsigned long)(component->latency * sampleRate / 3);
|
||||
bufSz = fragSz * 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_hostapi_skeleton.c 1668 2011-05-02 17:07:11Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library skeleton implementation
|
||||
* demonstrates how to use the common functions to implement support
|
||||
* for a host API
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
//
|
||||
// AudioSessionTypes.h -- Copyright Microsoft Corporation, All Rights Reserved.
|
||||
//
|
||||
// Description: Type definitions used by the audio session manager RPC/COM interfaces
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#ifndef __AUDIOSESSIONTYPES__
|
||||
#define __AUDIOSESSIONTYPES__
|
||||
|
||||
#if defined(__midl)
|
||||
#define MIDL_SIZE_IS(x) [size_is(x)]
|
||||
#define MIDL_STRING [string]
|
||||
#define MIDL_ANYSIZE_ARRAY
|
||||
#else // !defined(__midl)
|
||||
#define MIDL_SIZE_IS(x)
|
||||
#define MIDL_STRING
|
||||
#define MIDL_ANYSIZE_ARRAY ANYSIZE_ARRAY
|
||||
#endif // defined(__midl)
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Description: AudioClient share mode
|
||||
//
|
||||
// AUDCLNT_SHAREMODE_SHARED - The device will be opened in shared mode and use the
|
||||
// WAS format.
|
||||
// AUDCLNT_SHAREMODE_EXCLUSIVE - The device will be opened in exclusive mode and use the
|
||||
// application specified format.
|
||||
//
|
||||
typedef enum _AUDCLNT_SHAREMODE
|
||||
{
|
||||
AUDCLNT_SHAREMODE_SHARED,
|
||||
AUDCLNT_SHAREMODE_EXCLUSIVE
|
||||
} AUDCLNT_SHAREMODE;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Description: AudioClient stream flags
|
||||
//
|
||||
// Can be a combination of AUDCLNT_STREAMFLAGS and AUDCLNT_SYSFXFLAGS:
|
||||
//
|
||||
// AUDCLNT_STREAMFLAGS (this group of flags uses the high word, w/exception of high-bit which is reserved, 0x7FFF0000):
|
||||
//
|
||||
// AUDCLNT_STREAMFLAGS_CROSSPROCESS - Audio policy control for this stream will be shared with
|
||||
// with other process sessions that use the same audio session
|
||||
// GUID.
|
||||
// AUDCLNT_STREAMFLAGS_LOOPBACK - Initializes a renderer endpoint for a loopback audio application.
|
||||
// In this mode, a capture stream will be opened on the specified
|
||||
// renderer endpoint. Shared mode and a renderer endpoint is required.
|
||||
// Otherwise the IAudioClient::Initialize call will fail. If the
|
||||
// initialize is successful, a capture stream will be available
|
||||
// from the IAudioClient object.
|
||||
//
|
||||
// AUDCLNT_STREAMFLAGS_EVENTCALLBACK - An exclusive mode client will supply an event handle that will be
|
||||
// signaled when an IRP completes (or a waveRT buffer completes) telling
|
||||
// it to fill the next buffer
|
||||
//
|
||||
// AUDCLNT_STREAMFLAGS_NOPERSIST - Session state will not be persisted
|
||||
//
|
||||
// AUDCLNT_SYSFXFLAGS (these flags use low word 0x0000FFFF):
|
||||
//
|
||||
// none defined currently
|
||||
//
|
||||
#define AUDCLNT_STREAMFLAGS_CROSSPROCESS 0x00010000
|
||||
#define AUDCLNT_STREAMFLAGS_LOOPBACK 0x00020000
|
||||
#define AUDCLNT_STREAMFLAGS_EVENTCALLBACK 0x00040000
|
||||
#define AUDCLNT_STREAMFLAGS_NOPERSIST 0x00080000
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Description: Device share mode - sharing mode for the audio device.
|
||||
//
|
||||
// DeviceShared - The device can be shared with other processes.
|
||||
// DeviceExclusive - The device will only be used by this process.
|
||||
//
|
||||
typedef enum _DeviceShareMode
|
||||
{
|
||||
DeviceShared,
|
||||
DeviceExclusive
|
||||
} DeviceShareMode;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Description: AudioSession State.
|
||||
//
|
||||
// AudioSessionStateInactive - The session has no active audio streams.
|
||||
// AudioSessionStateActive - The session has active audio streams.
|
||||
// AudioSessionStateExpired - The session is dormant.
|
||||
typedef enum _AudioSessionState
|
||||
{
|
||||
AudioSessionStateInactive = 0,
|
||||
AudioSessionStateActive = 1,
|
||||
AudioSessionStateExpired = 2
|
||||
} AudioSessionState;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
|
||||
/*++
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
devpkey.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Defines property keys for the Plug and Play Device Property API.
|
||||
|
||||
Author:
|
||||
|
||||
Jim Cavalaris (jamesca) 10-14-2003
|
||||
|
||||
Environment:
|
||||
|
||||
User-mode only.
|
||||
|
||||
Revision History:
|
||||
|
||||
14-October-2003 jamesca
|
||||
|
||||
Creation and initial implementation.
|
||||
|
||||
20-June-2006 dougb
|
||||
|
||||
Copied Jim's version replaced "DEFINE_DEVPROPKEY(DEVPKEY_" with "DEFINE_PROPERTYKEY(PKEY_"
|
||||
|
||||
--*/
|
||||
|
||||
//#include <devpropdef.h>
|
||||
|
||||
//
|
||||
// _NAME
|
||||
//
|
||||
|
||||
DEFINE_PROPERTYKEY(PKEY_NAME, 0xb725f130, 0x47ef, 0x101a, 0xa5, 0xf1, 0x02, 0x60, 0x8c, 0x9e, 0xeb, 0xac, 10); // DEVPROP_TYPE_STRING
|
||||
|
||||
//
|
||||
// Device properties
|
||||
// These PKEYs correspond to the old setupapi SPDRP_XXX properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DeviceDesc, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 2); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_HardwareIds, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 3); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_CompatibleIds, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 4); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Service, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 6); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Class, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 9); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_ClassGuid, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 10); // DEVPROP_TYPE_GUID
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Driver, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 11); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_ConfigFlags, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 12); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Manufacturer, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 13); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_LocationInfo, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 15); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_PDOName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 16); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Capabilities, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 17); // DEVPROP_TYPE_UNINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_UINumber, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 18); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_UpperFilters, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 19); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_LowerFilters, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 20); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_BusTypeGuid, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 21); // DEVPROP_TYPE_GUID
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_LegacyBusType, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 22); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_BusNumber, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 23); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_EnumeratorName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 24); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Security, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 25); // DEVPROP_TYPE_SECURITY_DESCRIPTOR
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_SecuritySDS, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 26); // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DevType, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 27); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Exclusive, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 28); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Characteristics, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 29); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Address, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 30); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_UINumberDescFormat, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 31); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_PowerData, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 32); // DEVPROP_TYPE_BINARY
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_RemovalPolicy, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 33); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_RemovalPolicyDefault, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 34); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_RemovalPolicyOverride, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 35); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_InstallState, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 36); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_LocationPaths, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 37); // DEVPROP_TYPE_STRING_LIST
|
||||
|
||||
//
|
||||
// Device properties
|
||||
// These PKEYs correspond to a device's status and problem code
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DevNodeStatus, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 2); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_ProblemCode, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 3); // DEVPROP_TYPE_UINT32
|
||||
|
||||
//
|
||||
// Device properties
|
||||
// These PKEYs correspond to device relations
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_EjectionRelations, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 4); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_RemovalRelations, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 5); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_PowerRelations, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 6); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_BusRelations, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 7); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Parent, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 8); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Children, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 9); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Siblings, 0x4340a6c5, 0x93fa, 0x4706, 0x97, 0x2c, 0x7b, 0x64, 0x80, 0x08, 0xa5, 0xa7, 10); // DEVPROP_TYPE_STRING_LIST
|
||||
|
||||
//
|
||||
// Other Device properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Reported, 0x80497100, 0x8c73, 0x48b9, 0xaa, 0xd9, 0xce, 0x38, 0x7e, 0x19, 0xc5, 0x6e, 2); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_Legacy, 0x80497100, 0x8c73, 0x48b9, 0xaa, 0xd9, 0xce, 0x38, 0x7e, 0x19, 0xc5, 0x6e, 3); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_InstanceId, 0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57, 256); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Numa_Proximity_Domain, 0x540b947e, 0x8b40, 0x45bc, 0xa8, 0xa2, 0x6a, 0x0b, 0x89, 0x4c, 0xbd, 0xa2, 1); // DEVPROP_TYPE_UINT32
|
||||
|
||||
//
|
||||
// Device driver properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverDate, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 2); // DEVPROP_TYPE_FILETIME
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverVersion, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 3); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverDesc, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 4); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverInfPath, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 5); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverInfSection, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 6); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverInfSectionExt, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 7); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_MatchingDeviceId, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 8); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverProvider, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 9); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverPropPageProvider, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 10); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverCoInstallers, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 11); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_ResourcePickerTags, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 12); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_ResourcePickerExceptions, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 13); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverRank, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 14); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_DriverLogoLevel, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 15); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_NoConnectSound, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 17); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_Device_GenericDriverInstalled, 0xa8b865dd, 0x2e3d, 0x4094, 0xad, 0x97, 0xe5, 0x93, 0xa7, 0xc, 0x75, 0xd6, 18); // DEVPROP_TYPE_BOOLEAN
|
||||
|
||||
|
||||
//
|
||||
// Device properties that were set by the driver package that was installed
|
||||
// on the device.
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_DrvPkg_Model, 0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 2); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DrvPkg_VendorWebSite, 0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 3); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DrvPkg_DetailedDescription, 0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 4); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DrvPkg_DocumentationLink, 0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 5); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DrvPkg_Icon, 0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 6); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_DrvPkg_BrandingIcon, 0xcf73bb51, 0x3abf, 0x44a2, 0x85, 0xe0, 0x9a, 0x3d, 0xc7, 0xa1, 0x21, 0x32, 7); // DEVPROP_TYPE_STRING_LIST
|
||||
|
||||
//
|
||||
// Device setup class properties
|
||||
// These PKEYs correspond to the old setupapi SPCRP_XXX properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_UpperFilters, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 19); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_LowerFilters, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 20); // DEVPROP_TYPE_STRING_LIST
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_Security, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 25); // DEVPROP_TYPE_SECURITY_DESCRIPTOR
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_SecuritySDS, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 26); // DEVPROP_TYPE_SECURITY_DESCRIPTOR_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_DevType, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 27); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_Exclusive, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 28); // DEVPROP_TYPE_UINT32
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_Characteristics, 0x4321918b, 0xf69e, 0x470d, 0xa5, 0xde, 0x4d, 0x88, 0xc7, 0x5a, 0xd2, 0x4b, 29); // DEVPROP_TYPE_UINT32
|
||||
|
||||
//
|
||||
// Device setup class properties
|
||||
// These PKEYs correspond to registry values under the device class GUID key
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_Name, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 2); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_ClassName, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 3); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_Icon, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 4); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_ClassInstaller, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 5); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_PropPageProvider, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 6); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_NoInstallClass, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 7); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_NoDisplayClass, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 8); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_SilentInstall, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 9); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_NoUseClass, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 10); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_DefaultService, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 11); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_IconPath, 0x259abffc, 0x50a7, 0x47ce, 0xaf, 0x8, 0x68, 0xc9, 0xa7, 0xd7, 0x33, 0x66, 12); // DEVPROP_TYPE_STRING_LIST
|
||||
|
||||
//
|
||||
// Other Device setup class properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceClass_ClassCoInstallers, 0x713d1703, 0xa2e2, 0x49f5, 0x92, 0x14, 0x56, 0x47, 0x2e, 0xf3, 0xda, 0x5c, 2); // DEVPROP_TYPE_STRING_LIST
|
||||
|
||||
//
|
||||
// Device interface properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceInterface_FriendlyName, 0x026e516e, 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22, 2); // DEVPROP_TYPE_STRING
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceInterface_Enabled, 0x026e516e, 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22, 3); // DEVPROP_TYPE_BOOLEAN
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceInterface_ClassGuid, 0x026e516e, 0xb814, 0x414b, 0x83, 0xcd, 0x85, 0x6d, 0x6f, 0xef, 0x48, 0x22, 4); // DEVPROP_TYPE_GUID
|
||||
|
||||
//
|
||||
// Device interface class properties
|
||||
//
|
||||
DEFINE_PROPERTYKEY(PKEY_DeviceInterfaceClass_DefaultInterface, 0x14c83a99, 0x0b3f, 0x44b7, 0xbe, 0x4c, 0xa1, 0x78, 0xd3, 0x99, 0x05, 0x64, 2); // DEVPROP_TYPE_STRING
|
||||
|
||||
|
||||
|
||||
|
|
@ -417,6 +417,12 @@ DEFINE_GUIDSTRUCT("6994AD04-93EF-11D0-A3CC-00A0C9223196",KSCATEGORY_AUDIO);
|
|||
DEFINE_GUIDSTRUCT("6994AD05-93EF-11D0-A3CC-00A0C9223196",KSCATEGORY_VIDEO);
|
||||
#define KSCATEGORY_VIDEO DEFINE_GUIDNAMED(KSCATEGORY_VIDEO)
|
||||
|
||||
/* Added for Vista and later */
|
||||
#define STATIC_KSCATEGORY_REALTIME \
|
||||
0xEB115FFCL, 0x10C8, 0x4964, 0x83, 0x1D, 0x6D, 0xCB, 0x02, 0xE6, 0xF2, 0x3F
|
||||
DEFINE_GUIDSTRUCT("EB115FFC-10C8-4964-831D-6DCB02E6F23F", KSCATEGORY_REALTIME);
|
||||
#define KSCATEGORY_REALTIME DEFINE_GUIDNAMED(KSCATEGORY_REALTIME)
|
||||
|
||||
#define STATIC_KSCATEGORY_TEXT \
|
||||
0x6994AD06L,0x93EF,0x11D0,0xA3,0xCC,0x00,0xA0,0xC9,0x22,0x31,0x96
|
||||
DEFINE_GUIDSTRUCT("6994AD06-93EF-11D0-A3CC-00A0C9223196",KSCATEGORY_TEXT);
|
||||
|
@ -979,7 +985,15 @@ DEFINE_GUIDSTRUCT("A855A48C-2F78-4729-9051-1968746B9EEF",KSPROPSETID_RtAudio);
|
|||
#define KSPROPSETID_RtAudio DEFINE_GUIDNAMED(KSPROPSETID_RtAudio)
|
||||
|
||||
typedef enum {
|
||||
KSPROPERTY_RTAUDIO_GETPOSITIONFUNCTION
|
||||
KSPROPERTY_RTAUDIO_GETPOSITIONFUNCTION,
|
||||
/* Added for Vista and later */
|
||||
KSPROPERTY_RTAUDIO_BUFFER,
|
||||
KSPROPERTY_RTAUDIO_HWLATENCY,
|
||||
KSPROPERTY_RTAUDIO_POSITIONREGISTER,
|
||||
KSPROPERTY_RTAUDIO_CLOCKREGISTER,
|
||||
KSPROPERTY_RTAUDIO_BUFFER_WITH_NOTIFICATION,
|
||||
KSPROPERTY_RTAUDIO_REGISTER_NOTIFICATION_EVENT,
|
||||
KSPROPERTY_RTAUDIO_UNREGISTER_NOTIFICATION_EVENT
|
||||
} KSPROPERTY_RTAUDIO;
|
||||
|
||||
#define STATIC_KSPROPSETID_DrmAudioStream \
|
||||
|
@ -4547,5 +4561,50 @@ typedef struct _tagKSJACK_DESCRIPTION2
|
|||
DWORD JackCapabilities;
|
||||
} KSJACK_DESCRIPTION2, *PKSJACK_DESCRIPTION2;
|
||||
|
||||
/* Additional structs for Windows Vista and later */
|
||||
typedef struct _tagKSRTAUDIO_BUFFER_PROPERTY {
|
||||
KSPROPERTY Property;
|
||||
PVOID BaseAddress;
|
||||
ULONG RequestedBufferSize;
|
||||
} KSRTAUDIO_BUFFER_PROPERTY, *PKSRTAUDIO_BUFFER_PROPERTY;
|
||||
|
||||
typedef struct _tagKSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION {
|
||||
KSPROPERTY Property;
|
||||
PVOID BaseAddress;
|
||||
ULONG RequestedBufferSize;
|
||||
ULONG NotificationCount;
|
||||
} KSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION, *PKSRTAUDIO_BUFFER_PROPERTY_WITH_NOTIFICATION;
|
||||
|
||||
typedef struct _tagKSRTAUDIO_BUFFER {
|
||||
PVOID BufferAddress;
|
||||
ULONG ActualBufferSize;
|
||||
BOOL CallMemoryBarrier;
|
||||
} KSRTAUDIO_BUFFER, *PKSRTAUDIO_BUFFER;
|
||||
|
||||
typedef struct _tagKSRTAUDIO_HWLATENCY {
|
||||
ULONG FifoSize;
|
||||
ULONG ChipsetDelay;
|
||||
ULONG CodecDelay;
|
||||
} KSRTAUDIO_HWLATENCY, *PKSRTAUDIO_HWLATENCY;
|
||||
|
||||
typedef struct _tagKSRTAUDIO_HWREGISTER_PROPERTY {
|
||||
KSPROPERTY Property;
|
||||
PVOID BaseAddress;
|
||||
} KSRTAUDIO_HWREGISTER_PROPERTY, *PKSRTAUDIO_HWREGISTER_PROPERTY;
|
||||
|
||||
typedef struct _tagKSRTAUDIO_HWREGISTER {
|
||||
PVOID Register;
|
||||
ULONG Width;
|
||||
ULONGLONG Numerator;
|
||||
ULONGLONG Denominator;
|
||||
ULONG Accuracy;
|
||||
} KSRTAUDIO_HWREGISTER, *PKSRTAUDIO_HWREGISTER;
|
||||
|
||||
typedef struct _tagKSRTAUDIO_NOTIFICATION_EVENT_PROPERTY {
|
||||
KSPROPERTY Property;
|
||||
HANDLE NotificationEvent;
|
||||
} KSRTAUDIO_NOTIFICATION_EVENT_PROPERTY, *PKSRTAUDIO_NOTIFICATION_EVENT_PROPERTY;
|
||||
|
||||
|
||||
#endif /* _KSMEDIA_ */
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,225 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
sdkddkver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Master include file for versioning windows SDK/DDK.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _INC_SDKDDKVER
|
||||
#define _INC_SDKDDKVER
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// _WIN32_WINNT version constants
|
||||
//
|
||||
#define _WIN32_WINNT_NT4 0x0400
|
||||
#define _WIN32_WINNT_WIN2K 0x0500
|
||||
#define _WIN32_WINNT_WINXP 0x0501
|
||||
#define _WIN32_WINNT_WS03 0x0502
|
||||
#define _WIN32_WINNT_LONGHORN 0x0600
|
||||
|
||||
//
|
||||
// _WIN32_IE_ version constants
|
||||
//
|
||||
#define _WIN32_IE_IE20 0x0200
|
||||
#define _WIN32_IE_IE30 0x0300
|
||||
#define _WIN32_IE_IE302 0x0302
|
||||
#define _WIN32_IE_IE40 0x0400
|
||||
#define _WIN32_IE_IE401 0x0401
|
||||
#define _WIN32_IE_IE50 0x0500
|
||||
#define _WIN32_IE_IE501 0x0501
|
||||
#define _WIN32_IE_IE55 0x0550
|
||||
#define _WIN32_IE_IE60 0x0600
|
||||
#define _WIN32_IE_IE60SP1 0x0601
|
||||
#define _WIN32_IE_IE60SP2 0x0603
|
||||
#define _WIN32_IE_IE70 0x0700
|
||||
|
||||
//
|
||||
// IE <-> OS version mapping
|
||||
//
|
||||
// NT4 supports IE versions 2.0 -> 6.0 SP1
|
||||
#define _WIN32_IE_NT4 _WIN32_IE_IE20
|
||||
#define _WIN32_IE_NT4SP1 _WIN32_IE_IE20
|
||||
#define _WIN32_IE_NT4SP2 _WIN32_IE_IE20
|
||||
#define _WIN32_IE_NT4SP3 _WIN32_IE_IE302
|
||||
#define _WIN32_IE_NT4SP4 _WIN32_IE_IE401
|
||||
#define _WIN32_IE_NT4SP5 _WIN32_IE_IE401
|
||||
#define _WIN32_IE_NT4SP6 _WIN32_IE_IE50
|
||||
// Win98 supports IE versions 4.01 -> 6.0 SP1
|
||||
#define _WIN32_IE_WIN98 _WIN32_IE_IE401
|
||||
// Win98SE supports IE versions 5.0 -> 6.0 SP1
|
||||
#define _WIN32_IE_WIN98SE _WIN32_IE_IE50
|
||||
// WinME supports IE versions 5.5 -> 6.0 SP1
|
||||
#define _WIN32_IE_WINME _WIN32_IE_IE55
|
||||
// Win2k supports IE versions 5.01 -> 6.0 SP1
|
||||
#define _WIN32_IE_WIN2K _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP1 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP2 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP3 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_WIN2KSP4 _WIN32_IE_IE501
|
||||
#define _WIN32_IE_XP _WIN32_IE_IE60
|
||||
#define _WIN32_IE_XPSP1 _WIN32_IE_IE60SP1
|
||||
#define _WIN32_IE_XPSP2 _WIN32_IE_IE60SP2
|
||||
#define _WIN32_IE_WS03 0x0602
|
||||
#define _WIN32_IE_WS03SP1 _WIN32_IE_IE60SP2
|
||||
#define _WIN32_IE_LONGHORN _WIN32_IE_IE70
|
||||
|
||||
|
||||
//
|
||||
// NTDDI version constants
|
||||
//
|
||||
#define NTDDI_WIN2K 0x05000000
|
||||
#define NTDDI_WIN2KSP1 0x05000100
|
||||
#define NTDDI_WIN2KSP2 0x05000200
|
||||
#define NTDDI_WIN2KSP3 0x05000300
|
||||
#define NTDDI_WIN2KSP4 0x05000400
|
||||
|
||||
#define NTDDI_WINXP 0x05010000
|
||||
#define NTDDI_WINXPSP1 0x05010100
|
||||
#define NTDDI_WINXPSP2 0x05010200
|
||||
|
||||
#define NTDDI_WS03 0x05020000
|
||||
#define NTDDI_WS03SP1 0x05020100
|
||||
|
||||
#define NTDDI_LONGHORN 0x06000000
|
||||
|
||||
//
|
||||
// masks for version macros
|
||||
//
|
||||
#define OSVERSION_MASK 0xFFFF0000
|
||||
#define SPVERSION_MASK 0x0000FF00
|
||||
#define SUBVERSION_MASK 0x000000FF
|
||||
|
||||
|
||||
//
|
||||
// macros to extract various version fields from the NTDDI version
|
||||
//
|
||||
#define OSVER(Version) ((Version) & OSVERSION_MASK)
|
||||
#define SPVER(Version) (((Version) & SPVERSION_MASK) >> 8)
|
||||
#define SUBVER(Version) (((Version) & SUBVERSION_MASK) )
|
||||
|
||||
|
||||
#if defined(DECLSPEC_DEPRECATED_DDK)
|
||||
|
||||
// deprecate in 2k or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WIN2K)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2K DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2K
|
||||
#endif
|
||||
|
||||
// deprecate in XP or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WINXP DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WINXP
|
||||
#endif
|
||||
|
||||
// deprecate in WS03 or later
|
||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2003 DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_WIN2003
|
||||
#endif
|
||||
|
||||
// deprecate in WS03 or later
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||
#define DECLSPEC_DEPRECATED_DDK_LONGHORN DECLSPEC_DEPRECATED_DDK
|
||||
#else
|
||||
#define DECLSPEC_DEPRECATED_DDK_LONGHORN
|
||||
#endif
|
||||
|
||||
#endif // defined(DECLSPEC_DEPRECATED_DDK)
|
||||
|
||||
|
||||
//
|
||||
// if versions aren't already defined, default to most current
|
||||
//
|
||||
|
||||
#define NTDDI_VERSION_FROM_WIN32_WINNT2(ver) ver##0000
|
||||
#define NTDDI_VERSION_FROM_WIN32_WINNT(ver) NTDDI_VERSION_FROM_WIN32_WINNT2(ver)
|
||||
|
||||
#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
|
||||
#define _WIN32_WINNT 0x0600
|
||||
#endif
|
||||
|
||||
#ifndef NTDDI_VERSION
|
||||
#ifdef _WIN32_WINNT
|
||||
// set NTDDI_VERSION based on _WIN32_WINNT
|
||||
#define NTDDI_VERSION NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT)
|
||||
#else
|
||||
#define NTDDI_VERSION 0x06000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WINVER
|
||||
#ifdef _WIN32_WINNT
|
||||
// set WINVER based on _WIN32_WINNT
|
||||
#define WINVER _WIN32_WINNT
|
||||
#else
|
||||
#define WINVER 0x0600
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_IE
|
||||
#ifdef _WIN32_WINNT
|
||||
// set _WIN32_IE based on _WIN32_WINNT
|
||||
#if (_WIN32_WINNT <= _WIN32_WINNT_NT4)
|
||||
#define _WIN32_IE _WIN32_IE_IE50
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WIN2K)
|
||||
#define _WIN32_IE _WIN32_IE_IE501
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WINXP)
|
||||
#define _WIN32_IE _WIN32_IE_IE60
|
||||
#elif (_WIN32_WINNT <= _WIN32_WINNT_WS03)
|
||||
#define _WIN32_IE 0x0602
|
||||
#else
|
||||
#define _WIN32_IE 0x0700
|
||||
#endif
|
||||
#else
|
||||
#define _WIN32_IE 0x0700
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Sanity check for compatible versions
|
||||
//
|
||||
#if defined(_WIN32_WINNT) && !defined(MIDL_PASS) && !defined(RC_INVOKED)
|
||||
|
||||
#if (defined(WINVER) && (WINVER < 0x0400) && (_WIN32_WINNT > 0x0400))
|
||||
#error WINVER setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WIN2K) && (_WIN32_WINNT != _WIN32_WINNT_WIN2K))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WINXP) && (_WIN32_WINNT != _WIN32_WINNT_WINXP))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_WS03) && (_WIN32_WINNT != _WIN32_WINNT_WS03))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if (((OSVERSION_MASK & NTDDI_VERSION) == NTDDI_LONGHORN) && (_WIN32_WINNT != _WIN32_WINNT_LONGHORN))
|
||||
#error NTDDI_VERSION setting conflicts with _WIN32_WINNT setting
|
||||
#endif
|
||||
|
||||
#if ((_WIN32_WINNT < _WIN32_WINNT_WIN2K) && (_WIN32_IE > _WIN32_IE_IE60SP1))
|
||||
#error _WIN32_WINNT settings conflicts with _WIN32_IE setting
|
||||
#endif
|
||||
|
||||
#endif // defined(_WIN32_WINNT) && !defined(MIDL_PASS) && !defined(_WINRESRC_)
|
||||
|
||||
|
||||
#endif // !_INC_SDKDDKVER
|
||||
|
||||
|
|
@ -1,468 +0,0 @@
|
|||
|
||||
|
||||
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 7.00.0499 */
|
||||
/* Compiler settings for shtypes.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run)
|
||||
protocol : dce , ms_ext, c_ext, robust
|
||||
error checks: allocation ref bounds_check enum stub_data
|
||||
VC __declspec() decoration level:
|
||||
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
|
||||
DECLSPEC_UUID(), MIDL_INTERFACE()
|
||||
*/
|
||||
//@@MIDL_FILE_HEADING( )
|
||||
|
||||
#pragma warning( disable: 4049 ) /* more than 64k source lines */
|
||||
|
||||
|
||||
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 500
|
||||
#endif
|
||||
|
||||
/* verify that the <rpcsal.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCSAL_H_VERSION__
|
||||
#define __REQUIRED_RPCSAL_H_VERSION__ 100
|
||||
#endif
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#ifndef __RPCNDR_H_VERSION__
|
||||
#error this stub requires an updated version of <rpcndr.h>
|
||||
#endif // __RPCNDR_H_VERSION__
|
||||
|
||||
|
||||
#ifndef __shtypes_h__
|
||||
#define __shtypes_h__
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
/* header files for imported files */
|
||||
#include "wtypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
|
||||
/* interface __MIDL_itf_shtypes_0000_0000 */
|
||||
/* [local] */
|
||||
|
||||
//+-------------------------------------------------------------------------
|
||||
//
|
||||
// Microsoft Windows
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//===========================================================================
|
||||
//
|
||||
// Object identifiers in the explorer's name space (ItemID and IDList)
|
||||
//
|
||||
// All the items that the user can browse with the explorer (such as files,
|
||||
// directories, servers, work-groups, etc.) has an identifier which is unique
|
||||
// among items within the parent folder. Those identifiers are called item
|
||||
// IDs (SHITEMID). Since all its parent folders have their own item IDs,
|
||||
// any items can be uniquely identified by a list of item IDs, which is called
|
||||
// an ID list (ITEMIDLIST).
|
||||
//
|
||||
// ID lists are almost always allocated by the task allocator (see some
|
||||
// description below as well as OLE 2.0 SDK) and may be passed across
|
||||
// some of shell interfaces (such as IShellFolder). Each item ID in an ID list
|
||||
// is only meaningful to its parent folder (which has generated it), and all
|
||||
// the clients must treat it as an opaque binary data except the first two
|
||||
// bytes, which indicates the size of the item ID.
|
||||
//
|
||||
// When a shell extension -- which implements the IShellFolder interace --
|
||||
// generates an item ID, it may put any information in it, not only the data
|
||||
// with that it needs to identifies the item, but also some additional
|
||||
// information, which would help implementing some other functions efficiently.
|
||||
// For example, the shell's IShellFolder implementation of file system items
|
||||
// stores the primary (long) name of a file or a directory as the item
|
||||
// identifier, but it also stores its alternative (short) name, size and date
|
||||
// etc.
|
||||
//
|
||||
// When an ID list is passed to one of shell APIs (such as SHGetPathFromIDList),
|
||||
// it is always an absolute path -- relative from the root of the name space,
|
||||
// which is the desktop folder. When an ID list is passed to one of IShellFolder
|
||||
// member function, it is always a relative path from the folder (unless it
|
||||
// is explicitly specified).
|
||||
//
|
||||
//===========================================================================
|
||||
//
|
||||
// SHITEMID -- Item ID (mkid)
|
||||
// USHORT cb; // Size of the ID (including cb itself)
|
||||
// BYTE abID[]; // The item ID (variable length)
|
||||
//
|
||||
#include <pshpack1.h>
|
||||
typedef struct _SHITEMID
|
||||
{
|
||||
USHORT cb;
|
||||
BYTE abID[ 1 ];
|
||||
} SHITEMID;
|
||||
|
||||
#include <poppack.h>
|
||||
#if defined(_M_IX86)
|
||||
#define __unaligned
|
||||
#endif // __unaligned
|
||||
typedef SHITEMID __unaligned *LPSHITEMID;
|
||||
|
||||
typedef const SHITEMID __unaligned *LPCSHITEMID;
|
||||
|
||||
//
|
||||
// ITEMIDLIST -- List if item IDs (combined with 0-terminator)
|
||||
//
|
||||
#include <pshpack1.h>
|
||||
typedef struct _ITEMIDLIST
|
||||
{
|
||||
SHITEMID mkid;
|
||||
} ITEMIDLIST;
|
||||
|
||||
#if defined(STRICT_TYPED_ITEMIDS) && defined(__cplusplus)
|
||||
typedef struct _ITEMIDLIST_RELATIVE : ITEMIDLIST {} ITEMIDLIST_RELATIVE;
|
||||
typedef struct _ITEMID_CHILD : ITEMIDLIST_RELATIVE {} ITEMID_CHILD;
|
||||
typedef struct _ITEMIDLIST_ABSOLUTE : ITEMIDLIST_RELATIVE {} ITEMIDLIST_ABSOLUTE;
|
||||
#else // !(defined(STRICT_TYPED_ITEMIDS) && defined(__cplusplus))
|
||||
typedef ITEMIDLIST ITEMIDLIST_RELATIVE;
|
||||
|
||||
typedef ITEMIDLIST ITEMID_CHILD;
|
||||
|
||||
typedef ITEMIDLIST ITEMIDLIST_ABSOLUTE;
|
||||
|
||||
#endif // defined(STRICT_TYPED_ITEMIDS) && defined(__cplusplus)
|
||||
#include <poppack.h>
|
||||
typedef /* [unique] */ __RPC_unique_pointer BYTE_BLOB *wirePIDL;
|
||||
|
||||
typedef /* [wire_marshal] */ ITEMIDLIST __unaligned *LPITEMIDLIST;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMIDLIST __unaligned *LPCITEMIDLIST;
|
||||
|
||||
#if defined(STRICT_TYPED_ITEMIDS) && defined(__cplusplus)
|
||||
typedef /* [wire_marshal] */ ITEMIDLIST_ABSOLUTE *PIDLIST_ABSOLUTE;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMIDLIST_ABSOLUTE *PCIDLIST_ABSOLUTE;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMIDLIST_ABSOLUTE __unaligned *PCUIDLIST_ABSOLUTE;
|
||||
|
||||
typedef /* [wire_marshal] */ ITEMIDLIST_RELATIVE *PIDLIST_RELATIVE;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMIDLIST_RELATIVE *PCIDLIST_RELATIVE;
|
||||
|
||||
typedef /* [wire_marshal] */ ITEMIDLIST_RELATIVE __unaligned *PUIDLIST_RELATIVE;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMIDLIST_RELATIVE __unaligned *PCUIDLIST_RELATIVE;
|
||||
|
||||
typedef /* [wire_marshal] */ ITEMID_CHILD *PITEMID_CHILD;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMID_CHILD *PCITEMID_CHILD;
|
||||
|
||||
typedef /* [wire_marshal] */ ITEMID_CHILD __unaligned *PUITEMID_CHILD;
|
||||
|
||||
typedef /* [wire_marshal] */ const ITEMID_CHILD __unaligned *PCUITEMID_CHILD;
|
||||
|
||||
typedef const PCUITEMID_CHILD *PCUITEMID_CHILD_ARRAY;
|
||||
|
||||
typedef const PCUIDLIST_RELATIVE *PCUIDLIST_RELATIVE_ARRAY;
|
||||
|
||||
typedef const PCIDLIST_ABSOLUTE *PCIDLIST_ABSOLUTE_ARRAY;
|
||||
|
||||
typedef const PCUIDLIST_ABSOLUTE *PCUIDLIST_ABSOLUTE_ARRAY;
|
||||
|
||||
#else // !(defined(STRICT_TYPED_ITEMIDS) && defined(__cplusplus))
|
||||
#define PIDLIST_ABSOLUTE LPITEMIDLIST
|
||||
#define PCIDLIST_ABSOLUTE LPCITEMIDLIST
|
||||
#define PCUIDLIST_ABSOLUTE LPCITEMIDLIST
|
||||
#define PIDLIST_RELATIVE LPITEMIDLIST
|
||||
#define PCIDLIST_RELATIVE LPCITEMIDLIST
|
||||
#define PUIDLIST_RELATIVE LPITEMIDLIST
|
||||
#define PCUIDLIST_RELATIVE LPCITEMIDLIST
|
||||
#define PITEMID_CHILD LPITEMIDLIST
|
||||
#define PCITEMID_CHILD LPCITEMIDLIST
|
||||
#define PUITEMID_CHILD LPITEMIDLIST
|
||||
#define PCUITEMID_CHILD LPCITEMIDLIST
|
||||
#define PCUITEMID_CHILD_ARRAY LPCITEMIDLIST *
|
||||
#define PCUIDLIST_RELATIVE_ARRAY LPCITEMIDLIST *
|
||||
#define PCIDLIST_ABSOLUTE_ARRAY LPCITEMIDLIST *
|
||||
#define PCUIDLIST_ABSOLUTE_ARRAY LPCITEMIDLIST *
|
||||
#endif // defined(STRICT_TYPED_ITEMIDS) && defined(__cplusplus)
|
||||
#ifdef MIDL_PASS
|
||||
typedef struct _WIN32_FIND_DATAA
|
||||
{
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD dwReserved0;
|
||||
DWORD dwReserved1;
|
||||
CHAR cFileName[ 260 ];
|
||||
CHAR cAlternateFileName[ 14 ];
|
||||
} WIN32_FIND_DATAA;
|
||||
|
||||
typedef struct _WIN32_FIND_DATAA *PWIN32_FIND_DATAA;
|
||||
|
||||
typedef struct _WIN32_FIND_DATAA *LPWIN32_FIND_DATAA;
|
||||
|
||||
typedef struct _WIN32_FIND_DATAW
|
||||
{
|
||||
DWORD dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
DWORD nFileSizeHigh;
|
||||
DWORD nFileSizeLow;
|
||||
DWORD dwReserved0;
|
||||
DWORD dwReserved1;
|
||||
WCHAR cFileName[ 260 ];
|
||||
WCHAR cAlternateFileName[ 14 ];
|
||||
} WIN32_FIND_DATAW;
|
||||
|
||||
typedef struct _WIN32_FIND_DATAW *PWIN32_FIND_DATAW;
|
||||
|
||||
typedef struct _WIN32_FIND_DATAW *LPWIN32_FIND_DATAW;
|
||||
|
||||
#endif // MIDL_PASS
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// struct STRRET
|
||||
//
|
||||
// structure for returning strings from IShellFolder member functions
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// uType indicate which union member to use
|
||||
// STRRET_WSTR Use STRRET.pOleStr must be freed by caller of GetDisplayNameOf
|
||||
// STRRET_OFFSET Use STRRET.uOffset Offset into SHITEMID for ANSI string
|
||||
// STRRET_CSTR Use STRRET.cStr ANSI Buffer
|
||||
//
|
||||
typedef /* [v1_enum] */
|
||||
enum tagSTRRET_TYPE
|
||||
{ STRRET_WSTR = 0,
|
||||
STRRET_OFFSET = 0x1,
|
||||
STRRET_CSTR = 0x2
|
||||
} STRRET_TYPE;
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201) /* nonstandard extension used : nameless struct/union */
|
||||
#pragma once
|
||||
#endif
|
||||
#include <pshpack8.h>
|
||||
typedef struct _STRRET
|
||||
{
|
||||
UINT uType;
|
||||
union
|
||||
{
|
||||
LPWSTR pOleStr;
|
||||
UINT uOffset;
|
||||
char cStr[ 260 ];
|
||||
} DUMMYUNIONNAME;
|
||||
} STRRET;
|
||||
|
||||
#include <poppack.h>
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
typedef STRRET *LPSTRRET;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// struct SHELLDETAILS
|
||||
//
|
||||
// structure for returning strings from IShellDetails
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// fmt; // LVCFMT_* value (header only)
|
||||
// cxChar; // Number of 'average' characters (header only)
|
||||
// str; // String information
|
||||
//
|
||||
#include <pshpack1.h>
|
||||
typedef struct _SHELLDETAILS
|
||||
{
|
||||
int fmt;
|
||||
int cxChar;
|
||||
STRRET str;
|
||||
} SHELLDETAILS;
|
||||
|
||||
typedef struct _SHELLDETAILS *LPSHELLDETAILS;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
#if (_WIN32_IE >= _WIN32_IE_IE60SP2)
|
||||
typedef /* [v1_enum] */
|
||||
enum tagPERCEIVED
|
||||
{ PERCEIVED_TYPE_FIRST = -3,
|
||||
PERCEIVED_TYPE_CUSTOM = -3,
|
||||
PERCEIVED_TYPE_UNSPECIFIED = -2,
|
||||
PERCEIVED_TYPE_FOLDER = -1,
|
||||
PERCEIVED_TYPE_UNKNOWN = 0,
|
||||
PERCEIVED_TYPE_TEXT = 1,
|
||||
PERCEIVED_TYPE_IMAGE = 2,
|
||||
PERCEIVED_TYPE_AUDIO = 3,
|
||||
PERCEIVED_TYPE_VIDEO = 4,
|
||||
PERCEIVED_TYPE_COMPRESSED = 5,
|
||||
PERCEIVED_TYPE_DOCUMENT = 6,
|
||||
PERCEIVED_TYPE_SYSTEM = 7,
|
||||
PERCEIVED_TYPE_APPLICATION = 8,
|
||||
PERCEIVED_TYPE_GAMEMEDIA = 9,
|
||||
PERCEIVED_TYPE_CONTACTS = 10,
|
||||
PERCEIVED_TYPE_LAST = 10
|
||||
} PERCEIVED;
|
||||
|
||||
#define PERCEIVEDFLAG_UNDEFINED 0x0000
|
||||
#define PERCEIVEDFLAG_SOFTCODED 0x0001
|
||||
#define PERCEIVEDFLAG_HARDCODED 0x0002
|
||||
#define PERCEIVEDFLAG_NATIVESUPPORT 0x0004
|
||||
#define PERCEIVEDFLAG_GDIPLUS 0x0010
|
||||
#define PERCEIVEDFLAG_WMSDK 0x0020
|
||||
#define PERCEIVEDFLAG_ZIPFOLDER 0x0040
|
||||
typedef DWORD PERCEIVEDFLAG;
|
||||
|
||||
#endif // _WIN32_IE_IE60SP2
|
||||
|
||||
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
|
||||
typedef struct _COMDLG_FILTERSPEC
|
||||
{
|
||||
LPCWSTR pszName;
|
||||
LPCWSTR pszSpec;
|
||||
} COMDLG_FILTERSPEC;
|
||||
|
||||
typedef struct tagMACHINE_ID
|
||||
{
|
||||
char szName[ 16 ];
|
||||
} MACHINE_ID;
|
||||
|
||||
typedef struct tagDOMAIN_RELATIVE_OBJECTID
|
||||
{
|
||||
GUID guidVolume;
|
||||
GUID guidObject;
|
||||
} DOMAIN_RELATIVE_OBJECTID;
|
||||
|
||||
typedef GUID KNOWNFOLDERID;
|
||||
|
||||
#if 0
|
||||
typedef KNOWNFOLDERID *REFKNOWNFOLDERID;
|
||||
|
||||
#endif // 0
|
||||
#ifdef __cplusplus
|
||||
#define REFKNOWNFOLDERID const KNOWNFOLDERID &
|
||||
#else // !__cplusplus
|
||||
#define REFKNOWNFOLDERID const KNOWNFOLDERID * __MIDL_CONST
|
||||
#endif // __cplusplus
|
||||
#endif // NTDDI_LONGHORN
|
||||
typedef GUID FOLDERTYPEID;
|
||||
|
||||
#if 0
|
||||
typedef FOLDERTYPEID *REFFOLDERTYPEID;
|
||||
|
||||
#endif // 0
|
||||
#ifdef __cplusplus
|
||||
#define REFFOLDERTYPEID const FOLDERTYPEID &
|
||||
#else // !__cplusplus
|
||||
#define REFFOLDERTYPEID const FOLDERTYPEID * __MIDL_CONST
|
||||
#endif // __cplusplus
|
||||
typedef GUID TASKOWNERID;
|
||||
|
||||
#if 0
|
||||
typedef TASKOWNERID *REFTASKOWNERID;
|
||||
|
||||
#endif // 0
|
||||
#ifdef __cplusplus
|
||||
#define REFTASKOWNERID const TASKOWNERID &
|
||||
#else // !__cplusplus
|
||||
#define REFTASKOWNERID const TASKOWNERID * __MIDL_CONST
|
||||
#endif // __cplusplus
|
||||
#ifndef LF_FACESIZE
|
||||
typedef struct tagLOGFONTA
|
||||
{
|
||||
LONG lfHeight;
|
||||
LONG lfWidth;
|
||||
LONG lfEscapement;
|
||||
LONG lfOrientation;
|
||||
LONG lfWeight;
|
||||
BYTE lfItalic;
|
||||
BYTE lfUnderline;
|
||||
BYTE lfStrikeOut;
|
||||
BYTE lfCharSet;
|
||||
BYTE lfOutPrecision;
|
||||
BYTE lfClipPrecision;
|
||||
BYTE lfQuality;
|
||||
BYTE lfPitchAndFamily;
|
||||
CHAR lfFaceName[ 32 ];
|
||||
} LOGFONTA;
|
||||
|
||||
typedef struct tagLOGFONTW
|
||||
{
|
||||
LONG lfHeight;
|
||||
LONG lfWidth;
|
||||
LONG lfEscapement;
|
||||
LONG lfOrientation;
|
||||
LONG lfWeight;
|
||||
BYTE lfItalic;
|
||||
BYTE lfUnderline;
|
||||
BYTE lfStrikeOut;
|
||||
BYTE lfCharSet;
|
||||
BYTE lfOutPrecision;
|
||||
BYTE lfClipPrecision;
|
||||
BYTE lfQuality;
|
||||
BYTE lfPitchAndFamily;
|
||||
WCHAR lfFaceName[ 32 ];
|
||||
} LOGFONTW;
|
||||
|
||||
typedef LOGFONTA LOGFONT;
|
||||
|
||||
#endif // LF_FACESIZE
|
||||
typedef /* [v1_enum] */
|
||||
enum tagSHCOLSTATE
|
||||
{ SHCOLSTATE_TYPE_STR = 0x1,
|
||||
SHCOLSTATE_TYPE_INT = 0x2,
|
||||
SHCOLSTATE_TYPE_DATE = 0x3,
|
||||
SHCOLSTATE_TYPEMASK = 0xf,
|
||||
SHCOLSTATE_ONBYDEFAULT = 0x10,
|
||||
SHCOLSTATE_SLOW = 0x20,
|
||||
SHCOLSTATE_EXTENDED = 0x40,
|
||||
SHCOLSTATE_SECONDARYUI = 0x80,
|
||||
SHCOLSTATE_HIDDEN = 0x100,
|
||||
SHCOLSTATE_PREFER_VARCMP = 0x200,
|
||||
SHCOLSTATE_PREFER_FMTCMP = 0x400,
|
||||
SHCOLSTATE_NOSORTBYFOLDERNESS = 0x800,
|
||||
SHCOLSTATE_VIEWONLY = 0x10000,
|
||||
SHCOLSTATE_BATCHREAD = 0x20000,
|
||||
SHCOLSTATE_NO_GROUPBY = 0x40000,
|
||||
SHCOLSTATE_FIXED_WIDTH = 0x1000,
|
||||
SHCOLSTATE_NODPISCALE = 0x2000,
|
||||
SHCOLSTATE_FIXED_RATIO = 0x4000,
|
||||
SHCOLSTATE_DISPLAYMASK = 0xf000
|
||||
} SHCOLSTATE;
|
||||
|
||||
typedef DWORD SHCOLSTATEF;
|
||||
|
||||
typedef PROPERTYKEY SHCOLUMNID;
|
||||
|
||||
typedef const SHCOLUMNID *LPCSHCOLUMNID;
|
||||
|
||||
|
||||
|
||||
extern RPC_IF_HANDLE __MIDL_itf_shtypes_0000_0000_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE __MIDL_itf_shtypes_0000_0000_v0_0_s_ifspec;
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -2,24 +2,21 @@
|
|||
* WASAPI API *
|
||||
**************
|
||||
|
||||
----------------------------------------
|
||||
Microsoft Visual Studio 2005SP1/2008/10
|
||||
----------------------------------------
|
||||
No specific actions are needed to compile WASAPI API under Visual Studio.
|
||||
-------------------------------------------
|
||||
Microsoft Visual Studio 2005 SP1 and higher
|
||||
-------------------------------------------
|
||||
No specific action is required to compile WASAPI API under Visual Studio.
|
||||
You are only required to install min. Windows Vista SDK (v6.0A) prior
|
||||
compilation.
|
||||
the compilation. To compile with WASAPI specific functionality for Windows 8
|
||||
and higher the min. Windows 8 SDK is required.
|
||||
|
||||
----------------------------------------
|
||||
MinGW (GCC 32-bit)/ MinGW64 (GCC 64-bit)
|
||||
MinGW (GCC 32/64-bit)
|
||||
----------------------------------------
|
||||
To compile under MinGW you are required to include 'mingw-include' directory
|
||||
To compile with MinGW you are required to include 'mingw-include' directory
|
||||
which contains necessary files with WASAPI API. These files are modified
|
||||
in order to be compiled by MinGW compiler. These files are taken from
|
||||
Windows Vista SDK (v6.0A). MinGW compilation is tested and proved to be
|
||||
fully working under 32-bit and 64-bit modes.
|
||||
MinGW (32-bit) tested: gcc version 4.4.0 (GCC)
|
||||
MinGW64 (64-bit) tested: gcc version 4.4.4 20100226 (prerelease) (GCC)
|
||||
|
||||
PortAudio
|
||||
/Dmitry Kostjuchenko/
|
||||
04.03.2010
|
||||
for the compatibility with MinGW compiler. These files are taken from
|
||||
the Windows Vista SDK (v6.0A). MinGW compilation is tested and proved to be
|
||||
fully working.
|
||||
MinGW (32-bit) tested min. version: gcc version 4.4.0 (GCC)
|
||||
MinGW64 (64-bit) tested min. version: gcc version 4.4.4 20100226 (prerelease) (GCC)
|
File diff suppressed because it is too large
Load Diff
|
@ -3,12 +3,15 @@ Notes about WDM-KS host API
|
|||
|
||||
Status history
|
||||
--------------
|
||||
16th January 2011:
|
||||
Added support for WaveRT device API (Vista and later) for even lesser
|
||||
latency support.
|
||||
|
||||
10th November 2005:
|
||||
Made following changes:
|
||||
* OpenStream: Try all PaSampleFormats internally if the the chosen
|
||||
format is not supported natively. This fixed several problems
|
||||
with soundcards that soundcards that did not take kindly to
|
||||
using 24-bit 3-byte formats.
|
||||
with soundcards that did not take kindly to using 24-bit 3-byte formats.
|
||||
* OpenStream: Make the minimum framesPerHostIBuffer (and framesPerHostOBuffer)
|
||||
the default frameSize for the playback/recording pin.
|
||||
* ProcessingThread: Added a switch to only call PaUtil_EndBufferProcessing
|
||||
|
@ -71,7 +74,7 @@ In PortAudio terms, this means having a stream Open on a WDMKS device.
|
|||
Usage
|
||||
-----
|
||||
To add the WDMKS backend to your program which is already using
|
||||
PortAudio, you must undefine PA_NO_WDMKS from your build file,
|
||||
PortAudio, you must define PA_USE_WDMKS=1 in your build file,
|
||||
and include the pa_win_wdmks\pa_win_wdmks.c into your build.
|
||||
The file should compile in both C and C++.
|
||||
You will need a DirectX SDK installed on your system for the
|
||||
|
@ -79,4 +82,4 @@ ks.h and ksmedia.h header files.
|
|||
You will need to link to the system "setupapi" library.
|
||||
Note that if you use MinGW, you will get more warnings from
|
||||
the DX header files when using GCC(C), and still a few warnings
|
||||
with G++(CPP).
|
||||
with G++(CPP).
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_wmme.c 1739 2011-08-25 07:15:31Z rossb $
|
||||
* $Id$
|
||||
* pa_win_wmme.c
|
||||
* Implementation of PortAudio for Windows MultiMedia Extensions (WMME)
|
||||
*
|
||||
|
@ -62,7 +62,7 @@
|
|||
*/
|
||||
|
||||
/** @file
|
||||
@ingroup hostapi_src
|
||||
@ingroup hostapi_src
|
||||
|
||||
@brief Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API.
|
||||
*/
|
||||
|
@ -86,6 +86,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
@ -201,31 +202,52 @@
|
|||
static const char constInputMapperSuffix_[] = " - Input";
|
||||
static const char constOutputMapperSuffix_[] = " - Output";
|
||||
|
||||
/*
|
||||
copies TCHAR string to explicit char string
|
||||
*/
|
||||
char *StrTCpyToC(char *to, const TCHAR *from)
|
||||
/********************************************************************/
|
||||
|
||||
/* Copy null-terminated TCHAR string to explicit char string using UTF8 encoding */
|
||||
static char *CopyTCharStringToUtf8CString(char *destination, size_t destLengthBytes, const TCHAR *source)
|
||||
{
|
||||
#if !defined(_UNICODE) && !defined(UNICODE)
|
||||
return strcpy(to, from);
|
||||
return strcpy(destination, source);
|
||||
#else
|
||||
int count = wcslen(from);
|
||||
if (count != 0)
|
||||
if (WideCharToMultiByte(CP_ACP, 0, from, count, to, count, NULL, NULL) == 0)
|
||||
return NULL;
|
||||
return to;
|
||||
/* The cbMultiByte parameter ["destLengthBytes" below] is:
|
||||
"""
|
||||
Size, in bytes, of the buffer indicated by lpMultiByteStr ["destination" below].
|
||||
If this parameter is set to 0, the function returns the required buffer
|
||||
size for lpMultiByteStr and makes no use of the output parameter itself.
|
||||
"""
|
||||
Source: WideCharToMultiByte at MSDN:
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/dd374130(v=vs.85).aspx
|
||||
*/
|
||||
int intDestLengthBytes; /* cbMultiByte */
|
||||
/* intDestLengthBytes is an int, destLengthBytes is a size_t. Ensure that we don't overflow
|
||||
intDestLengthBytes by only using at most INT_MAX bytes of destination buffer.
|
||||
*/
|
||||
if (destLengthBytes < INT_MAX)
|
||||
{
|
||||
#pragma warning (disable : 4267) /* "conversion from 'size_t' to 'int', possible loss of data" */
|
||||
intDestLengthBytes = (int)destLengthBytes; /* destLengthBytes is guaranteed < INT_MAX here */
|
||||
#pragma warning (default : 4267)
|
||||
}
|
||||
else
|
||||
{
|
||||
intDestLengthBytes = INT_MAX;
|
||||
}
|
||||
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, source, -1, destination, /*cbMultiByte=*/intDestLengthBytes, NULL, NULL) == 0)
|
||||
return NULL;
|
||||
return destination;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
returns length of TCHAR string
|
||||
*/
|
||||
size_t StrTLen(const TCHAR *str)
|
||||
/* returns required length (in bytes) of destination buffer when
|
||||
converting TCHAR string to UTF8 bytes, not including the terminating null. */
|
||||
static size_t TCharStringLen(const TCHAR *str)
|
||||
{
|
||||
#if !defined(_UNICODE) && !defined(UNICODE)
|
||||
return strlen(str);
|
||||
return strlen(str);
|
||||
#else
|
||||
return wcslen(str);
|
||||
return WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -450,7 +472,7 @@ static PaDeviceIndex GetEnvDefaultDeviceID( char *envName )
|
|||
#ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */
|
||||
|
||||
/* Let user determine default device by setting environment variable. */
|
||||
hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE_ );
|
||||
hresult = GetEnvironmentVariableA( envName, envbuf, PA_ENV_BUF_SIZE_ );
|
||||
if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE_) )
|
||||
{
|
||||
recommendedIndex = atoi( envbuf );
|
||||
|
@ -491,7 +513,7 @@ static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hos
|
|||
{
|
||||
assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount );
|
||||
|
||||
return hostApi->winMmeDeviceIds[ device ];
|
||||
return hostApi->winMmeDeviceIds[ device ];
|
||||
}
|
||||
|
||||
|
||||
|
@ -686,6 +708,7 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
|||
MMRESULT mmresult;
|
||||
WAVEINCAPS wic;
|
||||
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
|
||||
size_t len;
|
||||
|
||||
*success = 0;
|
||||
|
||||
|
@ -705,29 +728,35 @@ static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeH
|
|||
return paNoError;
|
||||
}
|
||||
|
||||
/* NOTE: the WAVEOUTCAPS.szPname is a null-terminated array of 32 characters,
|
||||
so we are limited to displaying only the first 31 characters of the device name. */
|
||||
if( winMmeInputDeviceId == WAVE_MAPPER )
|
||||
{
|
||||
len = TCharStringLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_);
|
||||
/* Append I/O suffix to WAVE_MAPPER device. */
|
||||
deviceName = (char *)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_) );
|
||||
deviceName = (char*)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations,
|
||||
(long)len );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error;
|
||||
}
|
||||
StrTCpyToC( deviceName, wic.szPname );
|
||||
CopyTCharStringToUtf8CString( deviceName, len, wic.szPname );
|
||||
strcat( deviceName, constInputMapperSuffix_ );
|
||||
}
|
||||
else
|
||||
{
|
||||
len = TCharStringLen( wic.szPname ) + 1;
|
||||
deviceName = (char*)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( wic.szPname ) + 1 );
|
||||
winMmeHostApi->allocations,
|
||||
(long)len );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error;
|
||||
}
|
||||
StrTCpyToC( deviceName, wic.szPname );
|
||||
CopyTCharStringToUtf8CString( deviceName, len, wic.szPname );
|
||||
}
|
||||
deviceInfo->name = deviceName;
|
||||
|
||||
|
@ -809,6 +838,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
|||
MMRESULT mmresult;
|
||||
WAVEOUTCAPS woc;
|
||||
PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
|
||||
size_t len;
|
||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
||||
int wdmksDeviceOutputChannelCountIsKnown;
|
||||
#endif
|
||||
|
@ -831,29 +861,35 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
|||
return paNoError;
|
||||
}
|
||||
|
||||
/* NOTE: the WAVEOUTCAPS.szPname is a null-terminated array of 32 characters,
|
||||
so we are limited to displaying only the first 31 characters of the device name. */
|
||||
if( winMmeOutputDeviceId == WAVE_MAPPER )
|
||||
{
|
||||
/* Append I/O suffix to WAVE_MAPPER device. */
|
||||
deviceName = (char *)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_) );
|
||||
len = TCharStringLen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_);
|
||||
deviceName = (char*)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations,
|
||||
(long)len );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error;
|
||||
}
|
||||
StrTCpyToC( deviceName, woc.szPname );
|
||||
CopyTCharStringToUtf8CString( deviceName, len, woc.szPname );
|
||||
strcat( deviceName, constOutputMapperSuffix_ );
|
||||
}
|
||||
else
|
||||
{
|
||||
len = TCharStringLen( woc.szPname ) + 1;
|
||||
deviceName = (char*)PaUtil_GroupAllocateMemory(
|
||||
winMmeHostApi->allocations, StrTLen( woc.szPname ) + 1 );
|
||||
winMmeHostApi->allocations,
|
||||
(long)len );
|
||||
if( !deviceName )
|
||||
{
|
||||
result = paInsufficientMemory;
|
||||
goto error;
|
||||
}
|
||||
StrTCpyToC( deviceName, woc.szPname );
|
||||
CopyTCharStringToUtf8CString( deviceName, len, woc.szPname );
|
||||
}
|
||||
deviceInfo->name = deviceName;
|
||||
|
||||
|
@ -878,7 +914,7 @@ static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMme
|
|||
|
||||
#ifdef PAWIN_USE_WDMKS_DEVICE_INFO
|
||||
wdmksDeviceOutputChannelCountIsKnown = QueryWaveOutKSFilterMaxChannels(
|
||||
winMmeOutputDeviceId, &deviceInfo->maxOutputChannels );
|
||||
winMmeOutputDeviceId, &deviceInfo->maxOutputChannels );
|
||||
if( wdmksDeviceOutputChannelCountIsKnown && !winMmeDeviceInfo->deviceOutputChannelCountIsKnown )
|
||||
winMmeDeviceInfo->deviceOutputChannelCountIsKnown = 1;
|
||||
#endif /* PAWIN_USE_WDMKS_DEVICE_INFO */
|
||||
|
@ -897,9 +933,19 @@ error:
|
|||
|
||||
static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency )
|
||||
{
|
||||
/*
|
||||
NOTE: GetVersionEx() is deprecated as of Windows 8.1 and can not be used to reliably detect
|
||||
versions of Windows higher than Windows 8 (due to manifest requirements for reporting higher versions).
|
||||
Microsoft recommends switching to VerifyVersionInfo (available on Win 2k and later), however GetVersionEx
|
||||
is is faster, for now we just disable the deprecation warning.
|
||||
See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451(v=vs.85).aspx
|
||||
See: http://www.codeproject.com/Articles/678606/Part-Overcoming-Windows-s-deprecation-of-GetVe
|
||||
*/
|
||||
#pragma warning (disable : 4996) /* use of GetVersionEx */
|
||||
|
||||
OSVERSIONINFO osvi;
|
||||
osvi.dwOSVersionInfoSize = sizeof( osvi );
|
||||
GetVersionEx( &osvi );
|
||||
GetVersionEx( &osvi );
|
||||
|
||||
/* Check for NT */
|
||||
if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
|
||||
|
@ -916,6 +962,8 @@ static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighL
|
|||
}
|
||||
|
||||
*defaultHighLatency = *defaultLowLatency * 2;
|
||||
|
||||
#pragma warning (default : 4996)
|
||||
}
|
||||
|
||||
|
||||
|
@ -979,11 +1027,11 @@ PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
|
||||
inputDeviceCount = waveInGetNumDevs();
|
||||
if( inputDeviceCount > 0 )
|
||||
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
|
||||
maximumPossibleDeviceCount += inputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
|
||||
|
||||
outputDeviceCount = waveOutGetNumDevs();
|
||||
if( outputDeviceCount > 0 )
|
||||
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
|
||||
maximumPossibleDeviceCount += outputDeviceCount + 1; /* assume there is a WAVE_MAPPER */
|
||||
|
||||
|
||||
if( maximumPossibleDeviceCount > 0 ){
|
||||
|
@ -2153,29 +2201,29 @@ static PaError ValidateWinMmeSpecificStreamInfo(
|
|||
char *throttleProcessingThreadOnOverload,
|
||||
unsigned long *deviceCount )
|
||||
{
|
||||
if( streamInfo )
|
||||
{
|
||||
if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
|
||||
|| streamInfo->version != 1 )
|
||||
{
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
}
|
||||
if( streamInfo )
|
||||
{
|
||||
if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
|
||||
|| streamInfo->version != 1 )
|
||||
{
|
||||
return paIncompatibleHostApiSpecificStreamInfo;
|
||||
}
|
||||
|
||||
*winMmeSpecificFlags = streamInfo->flags;
|
||||
|
||||
if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
|
||||
*throttleProcessingThreadOnOverload = 0;
|
||||
if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
|
||||
*throttleProcessingThreadOnOverload = 0;
|
||||
|
||||
if( streamInfo->flags & paWinMmeUseMultipleDevices )
|
||||
{
|
||||
if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
|
||||
return paInvalidDevice;
|
||||
|
||||
*deviceCount = streamInfo->deviceCount;
|
||||
}
|
||||
}
|
||||
if( streamInfo->flags & paWinMmeUseMultipleDevices )
|
||||
{
|
||||
if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
|
||||
return paInvalidDevice;
|
||||
|
||||
*deviceCount = streamInfo->deviceCount;
|
||||
}
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
return paNoError;
|
||||
}
|
||||
|
||||
static PaError RetrieveDevicesFromStreamParameters(
|
||||
|
@ -2190,34 +2238,34 @@ static PaError RetrieveDevicesFromStreamParameters(
|
|||
int totalChannelCount;
|
||||
PaDeviceIndex hostApiDevice;
|
||||
|
||||
if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
|
||||
{
|
||||
totalChannelCount = 0;
|
||||
for( i=0; i < deviceCount; ++i )
|
||||
{
|
||||
/* validate that the device number is within range */
|
||||
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
|
||||
streamInfo->devices[i].device, hostApi );
|
||||
if( result != paNoError )
|
||||
return result;
|
||||
|
||||
devices[i].device = hostApiDevice;
|
||||
devices[i].channelCount = streamInfo->devices[i].channelCount;
|
||||
|
||||
totalChannelCount += devices[i].channelCount;
|
||||
}
|
||||
|
||||
if( totalChannelCount != streamParameters->channelCount )
|
||||
{
|
||||
/* channelCount must match total channels specified by multiple devices */
|
||||
return paInvalidChannelCount; /* REVIEW use of this error code */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
devices[0].device = streamParameters->device;
|
||||
devices[0].channelCount = streamParameters->channelCount;
|
||||
}
|
||||
if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
|
||||
{
|
||||
totalChannelCount = 0;
|
||||
for( i=0; i < deviceCount; ++i )
|
||||
{
|
||||
/* validate that the device number is within range */
|
||||
result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
|
||||
streamInfo->devices[i].device, hostApi );
|
||||
if( result != paNoError )
|
||||
return result;
|
||||
|
||||
devices[i].device = hostApiDevice;
|
||||
devices[i].channelCount = streamInfo->devices[i].channelCount;
|
||||
|
||||
totalChannelCount += devices[i].channelCount;
|
||||
}
|
||||
|
||||
if( totalChannelCount != streamParameters->channelCount )
|
||||
{
|
||||
/* channelCount must match total channels specified by multiple devices */
|
||||
return paInvalidChannelCount; /* REVIEW use of this error code */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
devices[0].device = streamParameters->device;
|
||||
devices[0].channelCount = streamParameters->channelCount;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -2231,10 +2279,10 @@ static PaError ValidateInputChannelCounts(
|
|||
PaWinMmeDeviceInfo *inputDeviceInfo;
|
||||
PaError paerror;
|
||||
|
||||
for( i=0; i < deviceCount; ++i )
|
||||
{
|
||||
for( i=0; i < deviceCount; ++i )
|
||||
{
|
||||
if( devices[i].channelCount < 1 )
|
||||
return paInvalidChannelCount;
|
||||
return paInvalidChannelCount;
|
||||
|
||||
inputDeviceInfo =
|
||||
(PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ];
|
||||
|
@ -2242,7 +2290,7 @@ static PaError ValidateInputChannelCounts(
|
|||
paerror = IsInputChannelCountSupported( inputDeviceInfo, devices[i].channelCount );
|
||||
if( paerror != paNoError )
|
||||
return paerror;
|
||||
}
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
@ -2256,10 +2304,10 @@ static PaError ValidateOutputChannelCounts(
|
|||
PaWinMmeDeviceInfo *outputDeviceInfo;
|
||||
PaError paerror;
|
||||
|
||||
for( i=0; i < deviceCount; ++i )
|
||||
{
|
||||
for( i=0; i < deviceCount; ++i )
|
||||
{
|
||||
if( devices[i].channelCount < 1 )
|
||||
return paInvalidChannelCount;
|
||||
return paInvalidChannelCount;
|
||||
|
||||
outputDeviceInfo =
|
||||
(PaWinMmeDeviceInfo*)hostApi->deviceInfos[ devices[i].device ];
|
||||
|
@ -2267,7 +2315,7 @@ static PaError ValidateOutputChannelCounts(
|
|||
paerror = IsOutputChannelCountSupported( outputDeviceInfo, devices[i].channelCount );
|
||||
if( paerror != paNoError )
|
||||
return paerror;
|
||||
}
|
||||
}
|
||||
|
||||
return paNoError;
|
||||
}
|
||||
|
@ -2316,28 +2364,28 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
if( inputParameters )
|
||||
{
|
||||
inputChannelCount = inputParameters->channelCount;
|
||||
inputChannelCount = inputParameters->channelCount;
|
||||
inputSampleFormat = inputParameters->sampleFormat;
|
||||
suggestedInputLatency = inputParameters->suggestedLatency;
|
||||
|
||||
inputDeviceCount = 1;
|
||||
inputDeviceCount = 1;
|
||||
|
||||
/* validate input hostApiSpecificStreamInfo */
|
||||
/* validate input hostApiSpecificStreamInfo */
|
||||
inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
|
||||
result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
|
||||
result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
|
||||
&winMmeSpecificInputFlags,
|
||||
&throttleProcessingThreadOnOverload,
|
||||
&inputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
&throttleProcessingThreadOnOverload,
|
||||
&inputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
|
||||
inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
|
||||
if( !inputDevices ) return paInsufficientMemory;
|
||||
|
||||
result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
hostInputSampleFormat =
|
||||
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
|
||||
|
@ -2353,7 +2401,7 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
else
|
||||
inputChannelMask = PaWin_DefaultChannelMask( inputDevices[0].channelCount );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inputChannelCount = 0;
|
||||
|
@ -2372,22 +2420,22 @@ static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
|
|||
|
||||
outputDeviceCount = 1;
|
||||
|
||||
/* validate output hostApiSpecificStreamInfo */
|
||||
/* validate output hostApiSpecificStreamInfo */
|
||||
outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
|
||||
result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
|
||||
result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
|
||||
&winMmeSpecificOutputFlags,
|
||||
&throttleProcessingThreadOnOverload,
|
||||
&outputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
&throttleProcessingThreadOnOverload,
|
||||
&outputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
|
||||
outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
|
||||
if( !outputDevices ) return paInsufficientMemory;
|
||||
|
||||
result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
|
||||
if( result != paNoError ) return result;
|
||||
|
||||
hostOutputSampleFormat =
|
||||
PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
|
||||
|
@ -3215,9 +3263,9 @@ static PaError StartStream( PaStream *s )
|
|||
MMRESULT mmresult;
|
||||
unsigned int i, j;
|
||||
int callbackResult;
|
||||
unsigned int channel;
|
||||
unsigned long framesProcessed;
|
||||
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
|
||||
unsigned int channel;
|
||||
unsigned long framesProcessed;
|
||||
PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
|
||||
|
||||
PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_unix_hostapis.c 1740 2011-08-25 07:17:48Z philburk $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library UNIX initialization table
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_unix_util.c 1510 2010-06-10 08:05:29Z dmitrykos $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* UNIX platform-specific support functions
|
||||
*
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_unix_util.h 1241 2007-07-23 20:08:31Z aknudsen $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* UNIX platform-specific support functions
|
||||
*
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#include "pa_win_coinitialize.h"
|
||||
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "ole32.lib" )
|
||||
#endif
|
||||
|
||||
|
@ -76,7 +76,11 @@ PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitial
|
|||
RPC_E_CHANGED_MODE was returned.
|
||||
*/
|
||||
|
||||
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP)
|
||||
hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */
|
||||
#else
|
||||
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
#endif
|
||||
if( FAILED(hr) && hr != RPC_E_CHANGED_MODE )
|
||||
{
|
||||
PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_hostapis.c 1728 2011-08-18 03:31:51Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library Windows initialization table
|
||||
*
|
||||
* Based on the Open Source API proposed by Ross Bencina
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* $Id: pa_win_util.c 1584 2011-02-02 18:58:17Z rossb $
|
||||
* $Id$
|
||||
* Portable Audio I/O Library
|
||||
* Win32 platform-specific support functions
|
||||
*
|
||||
|
@ -44,14 +44,17 @@
|
|||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h> /* for timeGetTime() */
|
||||
|
||||
#include "pa_util.h"
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "winmm.lib" )
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
#include <sys/timeb.h> /* for _ftime_s() */
|
||||
#else
|
||||
#include <mmsystem.h> /* for timeGetTime() */
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "winmm.lib" )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "pa_util.h"
|
||||
|
||||
/*
|
||||
Track memory allocations to avoid leaks.
|
||||
|
@ -144,8 +147,12 @@ double PaUtil_GetTime( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
#ifndef UNDER_CE
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
return GetTickCount64() * .001;
|
||||
#else
|
||||
return timeGetTime() * .001;
|
||||
#endif
|
||||
#else
|
||||
return GetTickCount() * .001;
|
||||
#endif
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
#include <mmreg.h> /* for WAVEFORMATEX */
|
||||
#endif
|
||||
|
||||
#include "portaudio.h"
|
||||
#include "pa_win_waveformat.h"
|
||||
|
@ -47,6 +50,7 @@
|
|||
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
|
||||
#endif
|
||||
|
||||
|
||||
static GUID pawin_ksDataFormatSubtypeGuidBase =
|
||||
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
|
||||
|
||||
|
@ -104,7 +108,6 @@ void PaWin_InitializeWaveFormatExtensible( PaWinWaveFormat *waveFormat,
|
|||
*((GUID*)&waveFormat->fields[PAWIN_INDEXOF_SUBFORMAT]) = guid;
|
||||
}
|
||||
|
||||
|
||||
PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
|
||||
{
|
||||
switch( numChannels ){
|
||||
|
@ -129,11 +132,16 @@ PaWinWaveFormatChannelMask PaWin_DefaultChannelMask( int numChannels )
|
|||
return PAWIN_SPEAKER_5POINT1;
|
||||
/* case 7: */
|
||||
case 8:
|
||||
return PAWIN_SPEAKER_7POINT1;
|
||||
/* 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;
|
||||
|
||||
|
|
|
@ -47,41 +47,53 @@
|
|||
#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"
|
||||
|
||||
#if !defined(PA_WDMKS_NO_KSGUID_LIB) && !defined(PAWIN_WDMKS_NO_KSGUID_LIB)
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "ksguid.lib" )
|
||||
#endif
|
||||
#define pa_KSDATAFORMAT_TYPE_AUDIO KSDATAFORMAT_TYPE_AUDIO
|
||||
#define pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
|
||||
#define pa_KSDATAFORMAT_SUBTYPE_PCM KSDATAFORMAT_SUBTYPE_PCM
|
||||
#define pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX KSDATAFORMAT_SUBTYPE_WAVEFORMATEX
|
||||
#define pa_KSMEDIUMSETID_Standard KSMEDIUMSETID_Standard
|
||||
#define pa_KSINTERFACESETID_Standard KSINTERFACESETID_Standard
|
||||
#define pa_KSPROPSETID_Pin KSPROPSETID_Pin
|
||||
#else
|
||||
static const GUID pa_KSDATAFORMAT_TYPE_AUDIO = { STATIC_KSDATAFORMAT_TYPE_AUDIO };
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM };
|
||||
static const GUID pa_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX = { STATIC_KSDATAFORMAT_SUBTYPE_WAVEFORMATEX };
|
||||
static const GUID pa_KSMEDIUMSETID_Standard = { STATIC_KSMEDIUMSETID_Standard };
|
||||
static const GUID pa_KSINTERFACESETID_Standard = { STATIC_KSINTERFACESETID_Standard };
|
||||
static const GUID pa_KSPROPSETID_Pin = { STATIC_KSPROPSETID_Pin };
|
||||
#endif
|
||||
|
||||
/* 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,
|
||||
|
|
|
@ -112,6 +112,18 @@ TODO:
|
|||
0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000
|
||||
*/
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32_WCE)
|
||||
|
||||
/*
|
||||
-EMT64/AMD64 uses different asm
|
||||
-VC2005 doesnt allow _WIN64 with inline assembly either!
|
||||
*/
|
||||
void PaUtil_InitializeX86PlainConverters( void )
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/
|
||||
|
@ -130,19 +142,6 @@ static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32_WCE)
|
||||
|
||||
/*
|
||||
-EMT64/AMD64 uses different asm
|
||||
-VC2005 doesnt allow _WIN64 with inline assembly either!
|
||||
*/
|
||||
void PaUtil_InitializeX86PlainConverters( void )
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
static void Float32_To_Int32(
|
||||
void *destinationBuffer, signed int destinationStride,
|
||||
void *sourceBuffer, signed int sourceStride,
|
||||
|
|
Loading…
Reference in New Issue