#ifndef PA_MULTIDRIVERMODEL_H #define PA_MULTIDRIVERMODEL_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* This file contains the host-neutral code for implementing multiple driver model support in PortAudio. It has not been compiled, but it is supplied only for example purposes at this stage. */ #include "portaudio.h" #define PA_MULTIDRIVER // for multidriver support TODO: declare function pointer types for the following function pointers /* Each driver model implementation needs to implement an initialize function which is added to the driverModelInitializers array in pa_multidrivermodel.c the initializer function needs to return a pointer to a PaDriverModelImplementation structure, or NULL if initiliazation failed. TODO: need error code instead the function pointer members of this structure point to funtions which operate in exactly the same way as the corresponding functions in the PortAudio API. */ struct{ fptr terminate; /* takes the PaDriverModelImplementation* returned by initialize */ fptr getDriverModelInfo; fptr getHostError; fptr getHostErrorText; fptr countDevices; fptr getDefaultInputDeviceID; fptr getDefaultOutputDeviceID; fptr getDeviceInfo; fptr openStream; fptr getMinNumBuffers; } PaDriverModelImplementation; /* whenever an implementaion's openstream method is called it should return a PortAudioStream* whose first segment is actually the following structure. the functions pointer members of this structure point to funcitons which operate in exactly the same way as the corresponding functions in the PortAudio API. */ struct{ unsigned long magic; fptr close; fptr start; fptr stop; fptr abort; fptr active; fptr time; fptr cpuLoad; } PaStreamImplementation; /* Implementations should set magic to PA_STREAM_MAGIC when opening a stream _and_ clear it to zero when closing a stream. All functions which operate on streams should check the validity of magic. */ #define PA_STREAM_MAGIC 0x12345678 #define PA_CHECK_STREAM( stream )\ if( ((PaStreamImplementation*)stream)->magic != PA_STREAM_MAGIC )\ return paBadStreamPtr; /* PA_API allows the same implementation to be used for single driver model and multi-driver model operation. If PA_MULTIDRIVER not defined, PA_API will declare api functions as global, otherwise they will be static, and include the drivermodel code. Usage would be something like: int PA_API(CountDevices)(); The PA_MULTIDRIVER_SUPPORT macro declares the initialization and termination functions required by the multidriver support. it also allocates and deallocates the PaDriverModelImplementation structure. TODO: add macros for initializing PaStreamImplementation PortAudioStream these would be PA_INITIALIZE_STREAM and PA_TERMINATE_STREAM they would assign and clear the magic number and assign the interface functions if neceassary. */ #ifdef PA_MULTIDRIVER #define PA_API( model, name ) static Pa ## model ## _ ## name #define PA_MULTIDRIVER_SUPPORT( model )\ PaError Pa_ ## model ## _MultiDriverTerminate( PaStreamImplementation *impl )\ {\ free( impl );\ return Pa ## model ## _Terminate();\ }\ PaError Pa ## model ## _MultiDriverInitialize( PaStreamImplementation** impl )\ {\ PaError result = Pa ## model ## _Initialize();\ \ if( result == paNoError ){\ *impl = malloc( sizeof( PaDriverModelImplementation ) );\ if( impl == NULL ){\ // TODO: call terminate, return an error }else{\ (*impl)->terminate = Pa ## model ## _MultiDriverTerminate();\ (*impl)->getDriverModelInfo = Pa ## model ## _GetDriverModelInfo();\ (*impl)->getHostError = Pa ## model ## _GetHostError();\ // TODO: assign the rest of the interface functions }\ }\ return result;\ } #else /* !PA_MULTIDRIVER */ #define PA_API( model, name ) Pa_ ## name #define PA_MULTIDRIVER_SUPPORT #endif /* PA_MULTIDRIVER */ #endif /* PA_MULTIDRIVERMODEL_H */