pa_win_wmme.c File Reference
Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API.
More...
#include <stdio.h>
#include <stdlib.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 |
Defines |
#define | CREATE_THREAD (HANDLE)_beginthreadex( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) |
#define | PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) |
#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) |
#define | PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_ (2) |
#define | PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_ (16) |
#define | PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) |
#define | PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) |
#define | PA_MME_WIN_NT_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2) |
#define | PA_MME_WIN_WDM_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_) |
#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) |
#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) |
int | PaWinMME_GetStreamInputHandleCount (PaStream *s) |
HWAVEIN | PaWinMME_GetStreamInputHandle (PaStream *s, int handleIndex) |
int | PaWinMME_GetStreamOutputHandleCount (PaStream *s) |
HWAVEOUT | PaWinMME_GetStreamOutputHandle (PaStream *s, int handleIndex) |
Detailed Description
Win32 host API implementation for the Windows MultiMedia Extensions (WMME) audio API.
- Todo:
- Fix buffer catch up code, can sometimes get stuck (perhaps fixed now, needs to be reviewed and tested.)
- Todo:
- implement paInputUnderflow, paOutputOverflow streamCallback statusFlags, paNeverDropInput.
- Todo:
- BUG: PA_MME_SET_LAST_WAVEIN/OUT_ERROR is used in functions which may be called asynchronously from the callback thread. this is bad.
- Todo:
- implement inputBufferAdcTime in callback thread
- Todo:
- review/fix error recovery and cleanup in marked functions
- Todo:
- implement timeInfo for stream priming
- Todo:
- handle the case where the callback returns paAbort or paComplete during stream priming.
- Todo:
- review input overflow and output underflow handling in ReadStream and WriteStream
Non-critical stuff for the future:
- Todo:
- Investigate supporting host buffer formats > 16 bits
- Todo:
- define UNICODE and _UNICODE in the project settings and see what breaks
- Todo:
- refactor conversion of MMSYSTEM errors into PA arrors into a single function.
- Todo:
- cleanup WAVEFORMATEXTENSIBLE retry in InitializeWaveHandles to not use a for loop
Define Documentation
#define CREATE_THREAD (HANDLE)_beginthreadex( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId ) |
#define DRVM_MAPPER_PREFERRED_GET (0x2000+21) |
#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) |
#define PA_ENV_BUF_SIZE_ (32) |
#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_IS_INPUT_STREAM_ |
( |
stream |
|
) |
( stream ->input.waveHandles ) |
#define PA_IS_OUTPUT_STREAM_ |
( |
stream |
|
) |
( stream ->output.waveHandles ) |
#define PA_MME_MAX_HOST_BUFFER_BYTES_ (32 * 1024) |
#define PA_MME_MAX_HOST_BUFFER_SECS_ (0.1) |
#define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_ (16) |
#define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ (3) |
#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 |
|
) |
|
Value:{ \
char mmeErrorText[ MAXERRORLENGTH ]; \
waveInGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \
PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \
}
#define PA_MME_SET_LAST_WAVEOUT_ERROR |
( |
mmresult |
|
) |
|
Value:{ \
char mmeErrorText[ MAXERRORLENGTH ]; \
waveOutGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH ); \
PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText ); \
}
#define PA_MME_USE_HIGH_DEFAULT_LATENCY_ (0) |
#define PA_MME_WIN_9X_DEFAULT_LATENCY_ (0.2) |
#define PA_MME_WIN_NT_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2) |
#define PA_MME_WIN_WDM_DEFAULT_LATENCY_ (PA_MME_WIN_9X_DEFAULT_LATENCY_) |
#define PA_REC_IN_DEV_ENV_NAME_ ("PA_RECOMMENDED_INPUT_DEVICE") |
#define PA_REC_OUT_DEV_ENV_NAME_ ("PA_RECOMMENDED_OUTPUT_DEVICE") |
Typedef Documentation
Function Documentation
HWAVEIN PaWinMME_GetStreamInputHandle |
( |
PaStream * |
stream, |
|
|
int |
handleIndex | |
|
) |
| | |
int PaWinMME_GetStreamInputHandleCount |
( |
PaStream * |
stream |
) |
|
HWAVEOUT PaWinMME_GetStreamOutputHandle |
( |
PaStream * |
stream, |
|
|
int |
handleIndex | |
|
) |
| | |
int PaWinMME_GetStreamOutputHandleCount |
( |
PaStream * |
stream |
) |
|
References PaWinMmeHostApiRepresentation::allocations, PaWinMmeHostApiRepresentation::blockingStreamInterface, PaWinMmeHostApiRepresentation::callbackStreamInterface, PaDeviceInfo::defaultHighInputLatency, PaDeviceInfo::defaultHighOutputLatency, PaDeviceInfo::defaultLowInputLatency, PaDeviceInfo::defaultLowOutputLatency, PaWinMmeDeviceInfo::deviceInputChannelCountIsKnown, PaWinMmeDeviceInfo::deviceOutputChannelCountIsKnown, DRVM_MAPPER_PREFERRED_GET, 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(), PaDeviceInfo::structVersion, PaHostApiInfo::structVersion, PaWinMmeHostApiRepresentation::winMmeDeviceIds, and WriteStream().