PortAudio
2.0
|
Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API. More...
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <windows.h>
#include <mmsystem.h>
#include <process.h>
#include <assert.h>
#include <malloc.h>
#include <memory.h>
#include "portaudio.h"
#include "pa_trace.h"
#include "pa_util.h"
#include "pa_allocation.h"
#include "pa_hostapi.h"
#include "pa_stream.h"
#include "pa_cpuload.h"
#include "pa_process.h"
#include "pa_debugprint.h"
#include "pa_win_wmme.h"
#include "pa_win_waveformat.h"
Data Structures | |
struct | PaWinMmeHostApiRepresentation |
struct | PaWinMmeDeviceInfo |
struct | PaWinMmeSingleDirectionHandlesAndBuffers |
struct | PaWinMmeStream |
Macros | |
#define | CREATE_THREAD (HANDLE)_beginthreadex( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) |
#define | PA_THREAD_FUNC static unsigned WINAPI |
#define | PA_THREAD_ID unsigned |
#define | DWORD_PTR unsigned long |
#define | PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */ |
#define | PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.2) |
#define | PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (2) |
#define | PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (3) /* always use at least 3 input buffers for full duplex */ |
#define | PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (2) |
#define | PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_ (16) |
#define | PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) /* Do not exceed unless user buffer exceeds */ |
#define | PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ |
#define | PA_MME_WIN_NT_DEFAULT_LATENCY_ (0.4) |
#define | PA_MME_WIN_WDM_DEFAULT_LATENCY_ (0.090) |
#define | PA_MME_TARGET_HOST_BUFFER_COUNT_ 8 |
#define | PA_MME_MIN_TIMEOUT_MSEC_ (1000) |
#define | PA_MME_SET_LAST_WAVEIN_ERROR(mmresult) |
#define | PA_MME_SET_LAST_WAVEOUT_ERROR(mmresult) |
#define | PA_MME_SET_LAST_SYSTEM_ERROR(errorCode) PaMme_SetLastSystemError( errorCode ) |
#define | PA_ENV_BUF_SIZE_ (32) |
#define | PA_REC_IN_DEV_ENV_NAME_ ("PA_RECOMMENDED_INPUT_DEVICE") |
#define | PA_REC_OUT_DEV_ENV_NAME_ ("PA_RECOMMENDED_OUTPUT_DEVICE") |
#define | PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ |
#define | DRVM_MAPPER_PREFERRED_GET (0x2000+21) |
#define | PA_IS_INPUT_STREAM_(stream) ( stream ->input.waveHandles ) |
#define | PA_IS_OUTPUT_STREAM_(stream) ( stream ->output.waveHandles ) |
#define | PA_IS_FULL_DUPLEX_STREAM_(stream) ( stream ->input.waveHandles && stream ->output.waveHandles ) |
#define | PA_IS_HALF_DUPLEX_STREAM_(stream) ( !(stream ->input.waveHandles && stream ->output.waveHandles) ) |
#define | PA_CIRCULAR_INCREMENT_(current, max) ( (((current) + 1) >= (max)) ? (0) : (current+1) ) |
#define | PA_CIRCULAR_DECREMENT_(current, max) ( ((current) == 0) ? ((max)-1) : (current-1) ) |
Typedefs | |
typedef struct PaWinMmeStream | PaWinMmeStream |
Functions | |
PaError | PaWinMme_Initialize (PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index) |
PA_THREAD_FUNC | ProcessingThreadProc (void *pArg) |
int | PaWinMME_GetStreamInputHandleCount (PaStream *s) |
HWAVEIN | PaWinMME_GetStreamInputHandle (PaStream *s, int handleIndex) |
int | PaWinMME_GetStreamOutputHandleCount (PaStream *s) |
HWAVEOUT | PaWinMME_GetStreamOutputHandle (PaStream *s, int handleIndex) |
Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API.
#define CREATE_THREAD (HANDLE)_beginthreadex( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) |
#define DRVM_MAPPER_PREFERRED_GET (0x2000+21) |
Referenced by PaWinMme_Initialize().
#define DWORD_PTR unsigned long |
Referenced by PaWinMme_Initialize().
#define PA_CIRCULAR_DECREMENT_ | ( | current, | |
max | |||
) | ( ((current) == 0) ? ((max)-1) : (current-1) ) |
#define PA_CIRCULAR_INCREMENT_ | ( | current, | |
max | |||
) | ( (((current) + 1) >= (max)) ? (0) : (current+1) ) |
#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ (13) /* must match array length below */ |
#define PA_ENV_BUF_SIZE_ (32) |
#define PA_IS_FULL_DUPLEX_STREAM_ | ( | stream | ) | ( stream ->input.waveHandles && stream ->output.waveHandles ) |
Referenced by ProcessingThreadProc().
#define PA_IS_HALF_DUPLEX_STREAM_ | ( | stream | ) | ( !(stream ->input.waveHandles && stream ->output.waveHandles) ) |
Referenced by ProcessingThreadProc().
#define PA_IS_INPUT_STREAM_ | ( | stream | ) | ( stream ->input.waveHandles ) |
Referenced by PaWinMME_GetStreamInputHandle(), PaWinMME_GetStreamInputHandleCount(), and ProcessingThreadProc().
#define PA_IS_OUTPUT_STREAM_ | ( | stream | ) | ( stream ->output.waveHandles ) |
Referenced by PaWinMME_GetStreamOutputHandle(), PaWinMME_GetStreamOutputHandleCount(), and ProcessingThreadProc().
#define PA_MME_HOST_BUFFER_GRANULARITY_FRAMES_WHEN_UNSPECIFIED_ (16) |
#define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */ |
#define PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) /* Do not exceed unless user buffer exceeds */ |
#define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (3) /* always use at least 3 input buffers for full duplex */ |
#define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (2) |
#define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_ (2) |
#define PA_MME_MIN_TIMEOUT_MSEC_ (1000) |
#define PA_MME_SET_LAST_SYSTEM_ERROR | ( | errorCode | ) | PaMme_SetLastSystemError( errorCode ) |
#define PA_MME_SET_LAST_WAVEIN_ERROR | ( | mmresult | ) |
#define PA_MME_SET_LAST_WAVEOUT_ERROR | ( | mmresult | ) |
#define PA_MME_TARGET_HOST_BUFFER_COUNT_ 8 |
#define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) /* For debugging glitches. */ |
#define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.2) |
#define PA_MME_WIN_NT_DEFAULT_LATENCY_ (0.4) |
#define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (0.090) |
#define PA_REC_IN_DEV_ENV_NAME_ ("PA_RECOMMENDED_INPUT_DEVICE") |
#define PA_REC_OUT_DEV_ENV_NAME_ ("PA_RECOMMENDED_OUTPUT_DEVICE") |
#define PA_THREAD_FUNC static unsigned WINAPI |
#define PA_THREAD_ID unsigned |
typedef struct PaWinMmeStream PaWinMmeStream |
HWAVEIN PaWinMME_GetStreamInputHandle | ( | PaStream * | stream, |
int | handleIndex | ||
) |
Retrieve a wave in handle used by a PortAudio WinMME stream.
stream | The stream to query. |
handleIndex | The zero based index of the wave in handle to retrieve. This should be in the range [0, PaWinMME_GetStreamInputHandleCount(stream)-1]. |
References PaWinMmeStream::input, PA_IS_INPUT_STREAM_, paNoError, and PaWinMmeSingleDirectionHandlesAndBuffers::waveHandles.
int PaWinMME_GetStreamInputHandleCount | ( | PaStream * | stream | ) |
Retrieve the number of wave in handles used by a PortAudio WinMME stream. Returns zero if the stream is output only.
References PaWinMmeSingleDirectionHandlesAndBuffers::deviceCount, PaWinMmeStream::input, PA_IS_INPUT_STREAM_, and paNoError.
HWAVEOUT PaWinMME_GetStreamOutputHandle | ( | PaStream * | stream, |
int | handleIndex | ||
) |
Retrieve a wave out handle used by a PortAudio WinMME stream.
stream | The stream to query. |
handleIndex | The zero based index of the wave out handle to retrieve. This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1]. |
References PaWinMmeStream::output, PA_IS_OUTPUT_STREAM_, paNoError, and PaWinMmeSingleDirectionHandlesAndBuffers::waveHandles.
int PaWinMME_GetStreamOutputHandleCount | ( | PaStream * | stream | ) |
Retrieve the number of wave out handles used by a PortAudio WinMME stream. Returns zero if the stream is input only.
References PaWinMmeSingleDirectionHandlesAndBuffers::deviceCount, PaWinMmeStream::output, PA_IS_OUTPUT_STREAM_, and paNoError.
PaError PaWinMme_Initialize | ( | PaUtilHostApiRepresentation ** | hostApi, |
PaHostApiIndex | index | ||
) |
References PaWinMmeHostApiRepresentation::allocations, PaWinMmeHostApiRepresentation::blockingStreamInterface, PaWinMmeHostApiRepresentation::callbackStreamInterface, PaDeviceInfo::defaultHighInputLatency, PaDeviceInfo::defaultHighOutputLatency, PaDeviceInfo::defaultLowInputLatency, PaDeviceInfo::defaultLowOutputLatency, PaWinMmeDeviceInfo::deviceInputChannelCountIsKnown, PaWinMmeDeviceInfo::deviceOutputChannelCountIsKnown, DRVM_MAPPER_PREFERRED_GET, DWORD_PTR, GetStreamReadAvailable(), GetStreamWriteAvailable(), PaDeviceInfo::hostApi, PaUtilHostApiRepresentation::info, PaWinMmeDeviceInfo::inheritedDeviceInfo, PaWinMmeHostApiRepresentation::inheritedHostApiRep, PaWinMmeHostApiRepresentation::inputDeviceCount, PaDeviceInfo::maxInputChannels, PaDeviceInfo::maxOutputChannels, PaWinMmeHostApiRepresentation::outputDeviceCount, paInsufficientMemory, paMME, paNoDevice, paNoError, PaUtil_AllocateMemory(), PaUtil_CreateAllocationGroup(), PaUtil_DestroyAllocationGroup(), PaUtil_DummyGetCpuLoad(), PaUtil_DummyGetReadAvailable(), PaUtil_DummyGetWriteAvailable(), PaUtil_DummyRead(), PaUtil_DummyWrite(), PaUtil_FreeAllAllocations(), PaUtil_FreeMemory(), PaUtil_GroupAllocateMemory(), PaUtil_InitializeStreamInterface(), ReadStream(), PaHostApiInfo::structVersion, PaDeviceInfo::structVersion, PaWinMmeHostApiRepresentation::winMmeDeviceIds, and WriteStream().
PA_THREAD_FUNC ProcessingThreadProc | ( | void * | pArg | ) |
note that it is also possible for an input overflow to happen while the callback is processing a buffer. that is handled further down.
References PaWinMmeStream::abortEvent, PaWinMmeStream::abortProcessing, PaWinMmeStream::allBuffersDurationMs, PaWinMmeSingleDirectionHandlesAndBuffers::bufferCount, PaWinMmeSingleDirectionHandlesAndBuffers::bufferEvent, PaWinMmeStream::bufferProcessor, PaUtilBufferProcessor::bytesPerHostInputSample, PaUtilBufferProcessor::bytesPerHostOutputSample, PaWinMmeStream::cpuLoadMeasurer, PaWinMmeSingleDirectionHandlesAndBuffers::currentBufferIndex, PaStreamCallbackTimeInfo::currentTime, PaWinMmeSingleDirectionHandlesAndBuffers::deviceCount, FALSE, PaWinMmeSingleDirectionHandlesAndBuffers::framesPerBuffer, PaUtilBufferProcessor::framesPerHostBuffer, PaWinMmeSingleDirectionHandlesAndBuffers::framesUsedInCurrentBuffer, HANDLE(), PaWinMmeStream::highThreadPriority, PaWinMmeStream::input, PaWinMmeStream::isActive, PaWinMmeStream::output, PaStreamCallbackTimeInfo::outputBufferDacTime, PA_IS_FULL_DUPLEX_STREAM_, PA_IS_HALF_DUPLEX_STREAM_, PA_IS_INPUT_STREAM_, PA_IS_OUTPUT_STREAM_, paAbort, paContinue, paInputOverflow, paNoError, paOutputUnderflow, paUnanticipatedHostError, PaUtil_BeginBufferProcessing(), PaUtil_BeginCpuLoadMeasurement(), PaUtil_EndBufferProcessing(), PaUtil_EndCpuLoadMeasurement(), PaUtil_GetCpuLoad(), PaUtil_GetTime(), PaUtil_ResetCpuLoadMeasurer(), PaUtil_SetInputFrameCount(), PaUtil_SetInterleavedInputChannels(), PaUtil_SetInterleavedOutputChannels(), PaUtil_SetOutputFrameCount(), PaUtil_ZeroOutput(), PaWinMmeStream::processingThread, PaWinMmeStream::processingThreadPriority, PaUtilBufferProcessor::samplePeriod, PaWinMmeStream::stopProcessing, PaUtilStreamRepresentation::streamFinishedCallback, PaWinMmeStream::streamRepresentation, PaWinMmeStream::throttledSleepMsecs, PaWinMmeStream::throttledThreadPriority, PaWinMmeStream::throttleProcessingThreadOnOverload, PaUtilStreamRepresentation::userData, PaWinMmeSingleDirectionHandlesAndBuffers::waveHandles, and PaWinMmeSingleDirectionHandlesAndBuffers::waveHeaders.