[PD-cvs] pd/portaudio/pa_dll_switch PaDllEntry.h, 1.2, 1.3 letter_from_tim_010817.txt, 1.2, 1.3 loadPA_DLL.cpp, 1.2, 1.3 pa_lib.c, 1.2, 1.3 portaudio.h, 1.2, 1.3

Miller Puckette millerpuckette at users.sourceforge.net
Sat Dec 31 01:59:51 CET 2005


Update of /cvsroot/pure-data/pd/portaudio/pa_dll_switch
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24040/portaudio/pa_dll_switch

Added Files:
	PaDllEntry.h letter_from_tim_010817.txt loadPA_DLL.cpp 
	pa_lib.c portaudio.h 
Log Message:
Added about 64 files that I hadn't realized weren't in the CVS
repository.  Threw in pd/portaudio/pa_win_wdmks for good measure, although
I haven't tried compiling that in yet (no windoze machine handy today).



--- NEW FILE: portaudio.h ---
#ifndef PORT_AUDIO_H
#define PORT_AUDIO_H

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

/*
 * PortAudio Portable Real-Time Audio Library
 * PortAudio API Header File
 * Latest version available at: http://www.audiomulch.com/portaudio/
 *
 * Copyright (c) 1999-2000 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.
 *
 * 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.
 *
 * 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.
 *
 */

// added by zplane.developement in order to generate a DLL

#if defined(PA_MME_EXPORTS) || defined(PA_DX_EXPORTS)
#define DLL_API __declspec( dllexport )
#elif defined(_LIB) || defined(_STATIC_LINK) || defined(_STATIC_APP)
#define DLL_API
#else
#define DLL_API __declspec(dllexport)
#endif


typedef int PaError;
typedef enum {
    paNoError = 0,

    paHostError = -10000,
    paInvalidChannelCount,
    paInvalidSampleRate,
    paInvalidDeviceId,
    paInvalidFlag,
    paSampleFormatNotSupported,
    paBadIODeviceCombination,
    paInsufficientMemory,
    paBufferTooBig,
    paBufferTooSmall,
    paNullCallback,
    paBadStreamPtr,
    paTimedOut,
    paInternalError
} PaErrorNum;

/*
 Pa_Initialize() is the library initialisation function - call this before
 using the library.
*/

DLL_API PaError Pa_Initialize( void );

/*
 Pa_Terminate() is the library termination function - call this after
 using the library.
*/

DLL_API PaError Pa_Terminate( void );

/*
 Return host specific error.
 This can be called after receiving a paHostError.
*/
DLL_API long Pa_GetHostError( void );

/*
 Translate the error number into a human readable message.
*/
DLL_API const char *Pa_GetErrorText( PaError errnum );

/*
 Sample formats
 
 These are formats used to pass sound data between the callback and the
 stream. Each device has a "native" format which may be used when optimum
 efficiency or control over conversion is required.
 
 Formats marked "always available" are supported (emulated) by all devices.
 
 The floating point representation uses +1.0 and -1.0 as the respective
 maximum and minimum.
 
*/

typedef unsigned long PaSampleFormat;
#define paFloat32      ((PaSampleFormat) (1<<0)) /*always available*/
#define paInt16        ((PaSampleFormat) (1<<1)) /*always available*/
#define paInt32        ((PaSampleFormat) (1<<2)) /*always available*/
#define paInt24        ((PaSampleFormat) (1<<3))
#define paPackedInt24  ((PaSampleFormat) (1<<4))
#define paInt8         ((PaSampleFormat) (1<<5))
#define paUInt8        ((PaSampleFormat) (1<<6))    /* unsigned 8 bit, 128 is "ground" */
#define paCustomFormat ((PaSampleFormat) (1<<16))

/*
 Device enumeration mechanism.
 
    Device ids range from 0 to Pa_CountDevices()-1.
 
 Devices may support input, output or both. Device 0 is always the "default"
 device and should support at least stereo in and out if that is available
 on the taget platform _even_ if this involves kludging an input/output
 device on platforms that usually separate input from output. Other platform
 specific devices are specified by positive device ids.
*/

typedef int PaDeviceID;
#define paNoDevice -1

typedef struct
{
    int structVersion;
    const char *name;
    int maxInputChannels;
    int maxOutputChannels;
    /* Number of discrete rates, or -1 if range supported. */
    int numSampleRates;
    /* Array of supported sample rates, or {min,max} if range supported. */
    const double *sampleRates;
    PaSampleFormat nativeSampleFormats;
}
PaDeviceInfo;


DLL_API int Pa_CountDevices();
/*
 Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()
 
 Return the default device ID or paNoDevice if there is no devices.
 The result can be passed to Pa_OpenStream().
 
 On the PC, the user can specify a default device by
 setting an environment variable. For example, to use device #1.
 
  set PA_RECOMMENDED_OUTPUT_DEVICE=1
 
 The user should first determine the available device ID by using
 the supplied application "pa_devs".
*/
DLL_API PaDeviceID Pa_GetDefaultInputDeviceID( void );
DLL_API PaDeviceID Pa_GetDefaultOutputDeviceID( void );

/*
 PaTimestamp is used to represent a continuous sample clock with arbitrary
 start time useful for syncronisation. The type is used in the outTime
 argument to the callback function and the result of Pa_StreamTime()
*/

typedef double PaTimestamp;

/*
 Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
 referring to the device specified by id.
 If id is out of range the function returns NULL.
 
 The returned structure is owned by the PortAudio implementation and must
 not be manipulated or freed. The pointer is guaranteed to be valid until
 between calls to Pa_Initialize() and Pa_Terminate().
*/

DLL_API const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id );

/*
 PortAudioCallback is implemented by clients of the portable audio api.
 
 inputBuffer and outputBuffer are arrays of interleaved samples,
 the format, packing and number of channels used by the buffers are
 determined by parameters to Pa_OpenStream() (see below).
 
 framesPerBuffer is the number of sample frames to be processed by the callback.
 
 outTime is the time in samples when the buffer(s) processed by
 this callback will begin being played at the audio output.
 See also Pa_StreamTime()
 
 userData is the value of a user supplied pointer passed to Pa_OpenStream()
 intended for storing synthesis data etc.
 
 return value:
 The callback can return a nonzero value to stop the stream. This may be
 useful in applications such as soundfile players where a specific duration
 of output is required. However, it is not necessary to utilise this mechanism
 as StopStream() will also terminate the stream. A callback returning a
 nonzero value must fill the entire outputBuffer.
 
 NOTE: None of the other stream functions may be called from within the
 callback function except for Pa_GetCPULoad().
 
*/

typedef int (PortAudioCallback)(
    void *inputBuffer, void *outputBuffer,
    unsigned long framesPerBuffer,
    PaTimestamp outTime, void *userData );


/*
 Stream flags
 
 These flags may be supplied (ored together) in the streamFlags argument to
 the Pa_OpenStream() function.
 
 [ suggestions? ]
*/

#define   paNoFlag      (0)
#define   paClipOff     (1<<0)   /* disable defult clipping of out of range samples */
#define   paDitherOff   (1<<1)   /* disable default dithering */
#define   paPlatformSpecificFlags (0x00010000)
typedef   unsigned long PaStreamFlags;

/*
 A single PortAudioStream provides multiple channels of real-time
 input and output audio streaming to a client application.
 Pointers to PortAudioStream objects are passed between PortAudio functions.
*/

typedef void PortAudioStream;
#define PaStream PortAudioStream

/*
 Pa_OpenStream() opens a stream for either input, output or both.
 
 stream is the address of a PortAudioStream pointer which will receive
 a pointer to the newly opened stream.
 
 inputDevice is the id of the device used for input (see PaDeviceID above.)
 inputDevice may be paNoDevice to indicate that an input device is not required.
 
 numInputChannels is the number of channels of sound to be delivered to the
 callback. It can range from 1 to the value of maxInputChannels in the
 device input record for the device specified in the inputDevice parameter.
 If inputDevice is paNoDevice numInputChannels is ignored.
 
 inputSampleFormat is the format of inputBuffer provided to the callback
 function. inputSampleFormat may be any of the formats described by the
 PaSampleFormat enumeration (see above). PortAudio guarantees support for
 the sound devices native formats (nativeSampleFormats in the device info
 record) and additionally 16 and 32 bit integer and 32 bit floating point
 formats. Support for other formats is implementation defined.
 
 inputDriverInfo is a pointer to an optional driver specific data structure
 containing additional information for device setup or stream processing.
 inputDriverInfo is never required for correct operation. If not used
 inputDriverInfo should be NULL.
 
 outputDevice is the id of the device used for output (see PaDeviceID above.)
 outputDevice may be paNoDevice to indicate that an output device is not required.
 
 numOutputChannels is the number of channels of sound to be supplied by the
 callback. See the definition of numInputChannels above for more details.
 
 outputSampleFormat is the sample format of the outputBuffer filled by the
 callback function. See the definition of inputSampleFormat above for more
 details.
 
 outputDriverInfo is a pointer to an optional driver specific data structure
 containing additional information for device setup or stream processing.
 outputDriverInfo is never required for correct operation. If not used
 outputDriverInfo should be NULL.
 
 sampleRate is the desired sampleRate for input and output
 
 framesPerBuffer is the length in sample frames of all internal sample buffers
 used for communication with platform specific audio routines. Wherever
 possible this corresponds to the framesPerBuffer parameter passed to the
 callback function.
 
 numberOfBuffers is the number of buffers used for multibuffered
 communication with the platform specific audio routines. This parameter is
 provided only as a guide - and does not imply that an implementation must
 use multibuffered i/o when reliable double buffering is available (such as
 SndPlayDoubleBuffer() on the Macintosh.)
 
 streamFlags may contain a combination of flags ORed together.
 These flags modify the behavior of the
 streaming process. Some flags may only be relevant to certain buffer formats.
 
 callback is a pointer to a client supplied function that is responsible
 for processing and filling input and output buffers (see above for details.)
 
 userData is a client supplied pointer which is passed to the callback
 function. It could for example, contain a pointer to instance data necessary
 for processing the audio buffers.
 
 return value:
 Apon success Pa_OpenStream() returns PaNoError and places a pointer to a
 valid PortAudioStream in the stream argument. The stream is inactive (stopped).
 If a call to Pa_OpenStream() fails a nonzero error code is returned (see
 PAError above) and the value of stream is invalid.
 
*/

DLL_API PaError Pa_OpenStream( PortAudioStream** stream,
                               PaDeviceID inputDevice,
                               int numInputChannels,
                               PaSampleFormat inputSampleFormat,
                               void *inputDriverInfo,
                               PaDeviceID outputDevice,
                               int numOutputChannels,
                               PaSampleFormat outputSampleFormat,
                               void *outputDriverInfo,
                               double sampleRate,
                               unsigned long framesPerBuffer,
                               unsigned long numberOfBuffers,
                               PaStreamFlags streamFlags,
                               PortAudioCallback *callback,
                               void *userData );


/*
 Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that
 opens the default input and/or ouput devices. Most parameters have
 identical meaning to their Pa_OpenStream() counterparts, with the following
 exceptions:
 
 If either numInputChannels or numOutputChannels is 0 the respective device
 is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )
 
 sampleFormat applies to both the input and output buffers.
*/

DLL_API PaError Pa_OpenDefaultStream( PortAudioStream** stream,
                                      int numInputChannels,
                                      int numOutputChannels,
                                      PaSampleFormat sampleFormat,
                                      double sampleRate,
                                      unsigned long framesPerBuffer,
                                      unsigned long numberOfBuffers,
                                      PortAudioCallback *callback,
                                      void *userData );

/*
 Pa_CloseStream() closes an audio stream, flushing any pending buffers.
*/

DLL_API PaError Pa_CloseStream( PortAudioStream* );

/*
  Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
 When Pa_StopStream() returns, all pending audio buffers have been played.
    Pa_AbortStream() stops playing immediately without waiting for pending
    buffers to complete.
*/

DLL_API PaError Pa_StartStream( PortAudioStream *stream );

DLL_API PaError Pa_StopStream( PortAudioStream *stream );

DLL_API PaError Pa_AbortStream( PortAudioStream *stream );

/*
 Pa_StreamActive() returns one when the stream is playing audio,
 zero when not playing, or a negative error number if the
 stream is invalid.
 The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
 but may also become inactive if the callback returns a non-zero value.
 In the latter case, the stream is considered inactive after the last
 buffer has finished playing.
*/

DLL_API PaError Pa_StreamActive( PortAudioStream *stream );

/*
 Pa_StreamTime() returns the current output time for the stream in samples.
 This time may be used as a time reference (for example syncronising audio to
 MIDI).
*/

DLL_API PaTimestamp Pa_StreamTime( PortAudioStream *stream );

/*
 The "CPU Load" is a fraction of total CPU time consumed by the
 stream's audio processing.
 A value of 0.5 would imply that PortAudio and the sound generating
 callback was consuming roughly 50% of the available CPU time.
 This function may be called from the callback function or the application.
*/
DLL_API double Pa_GetCPULoad( PortAudioStream* stream );

/*
 Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for
 the current host based on minimum latency. 
 On the PC, for the DirectSound implementation, latency can be optionally set
 by user by setting an environment variable.
 For example, to set latency to 200 msec, put:
 
    set PA_MIN_LATENCY_MSEC=200
 
 in the AUTOEXEC.BAT file and reboot.
 If the environment variable is not set, then the latency will be determined
 based on the OS. Windows NT has higher latency than Win95.
*/

DLL_API int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );

/*
 Sleep for at least 'msec' milliseconds.
 You may sleep longer than the requested time so don't rely
 on this for accurate musical timing.
*/
DLL_API void Pa_Sleep( long msec );

/*
 Return size in bytes of a single sample in a given PaSampleFormat
 or paSampleFormatNotSupported. 
*/
DLL_API PaError Pa_GetSampleSize( PaSampleFormat format );

#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PORT_AUDIO_H */

--- NEW FILE: PaDllEntry.h ---

/*
 * PortAudio Portable Real-Time Audio Library
 * PortAudio DLL Header File
 * Latest version available at: http://www.audiomulch.com/portaudio/
 *
 * Copyright (c) 1999-2000 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.
 *
 * 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.
 *
 * 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.
 *
 */

// changed by zplane.developement in order to generate a DLL

#ifndef __PADLLENTRY_HEADER_INCLUDED__

#define __PADLLENTRY_HEADER_INCLUDED__

typedef int PaError;
typedef enum {
    paNoError = 0,

    paHostError = -10000,
    paInvalidChannelCount,
    paInvalidSampleRate,
    paInvalidDeviceId,
    paInvalidFlag,
    paSampleFormatNotSupported,
    paBadIODeviceCombination,
    paInsufficientMemory,
    paBufferTooBig,
    paBufferTooSmall,
    paNullCallback,
    paBadStreamPtr,
    paTimedOut,
    paInternalError
} PaErrorNum;

typedef unsigned long PaSampleFormat;
#define paFloat32      ((PaSampleFormat) (1<<0)) /*always available*/
#define paInt16        ((PaSampleFormat) (1<<1)) /*always available*/
#define paInt32        ((PaSampleFormat) (1<<2)) /*always available*/
#define paInt24        ((PaSampleFormat) (1<<3))
#define paPackedInt24  ((PaSampleFormat) (1<<4))
#define paInt8         ((PaSampleFormat) (1<<5))
#define paUInt8        ((PaSampleFormat) (1<<6))    /* unsigned 8 bit, 128 is "ground" */
#define paCustomFormat ((PaSampleFormat) (1<<16))


typedef int PaDeviceID;
#define paNoDevice -1

typedef struct
{
    int structVersion;
    const char *name;
    int maxInputChannels;
    int maxOutputChannels;
    /* Number of discrete rates, or -1 if range supported. */
    int numSampleRates;
    /* Array of supported sample rates, or {min,max} if range supported. */
    const double *sampleRates;
    PaSampleFormat nativeSampleFormats;
}
PaDeviceInfo;


typedef double PaTimestamp;


typedef int (PortAudioCallback)(
    void *inputBuffer, void *outputBuffer,
    unsigned long framesPerBuffer,
    PaTimestamp outTime, void *userData );


#define   paNoFlag      (0)
#define   paClipOff     (1<<0)   /* disable default clipping of out of range samples */
#define   paDitherOff   (1<<1)   /* disable default dithering */
#define   paPlatformSpecificFlags (0x00010000)
typedef   unsigned long PaStreamFlags;

typedef void PortAudioStream;
#define PaStream PortAudioStream

extern  PaError (__cdecl* Pa_Initialize)( void );



extern  PaError (__cdecl* Pa_Terminate)( void );


extern  long (__cdecl* Pa_GetHostError)( void );


extern  const char* (__cdecl* Pa_GetErrorText)( PaError );



extern  int (__cdecl* Pa_CountDevices)(void);

extern  PaDeviceID (__cdecl* Pa_GetDefaultInputDeviceID)( void );

extern  PaDeviceID (__cdecl* Pa_GetDefaultOutputDeviceID)( void );


extern  const PaDeviceInfo* (__cdecl* Pa_GetDeviceInfo)( PaDeviceID);



extern  PaError (__cdecl* Pa_OpenStream)(
        PortAudioStream ** ,
        PaDeviceID ,
        int ,
        PaSampleFormat ,
        void *,
        PaDeviceID ,
        int ,
        PaSampleFormat ,
        void *,
        double ,
        unsigned long ,
        unsigned long ,
        unsigned long ,
        PortAudioCallback *,
        void * );



extern  PaError (__cdecl* Pa_OpenDefaultStream)( PortAudioStream** stream,
            int numInputChannels,
            int numOutputChannels,
            PaSampleFormat sampleFormat,
            double sampleRate,
            unsigned long framesPerBuffer,
            unsigned long numberOfBuffers,
            PortAudioCallback *callback,
            void *userData );


extern  PaError (__cdecl* Pa_CloseStream)( PortAudioStream* );


extern  PaError (__cdecl* Pa_StartStream)( PortAudioStream *stream );

extern  PaError (__cdecl* Pa_StopStream)( PortAudioStream *stream );

extern  PaError (__cdecl* Pa_AbortStream)( PortAudioStream *stream );

extern  PaError (__cdecl* Pa_StreamActive)( PortAudioStream *stream );

extern  PaTimestamp (__cdecl* Pa_StreamTime)( PortAudioStream *stream );

extern  double (__cdecl* Pa_GetCPULoad)( PortAudioStream* stream );

extern  int (__cdecl* Pa_GetMinNumBuffers)( int framesPerBuffer, double sampleRate );

extern  void (__cdecl* Pa_Sleep)( long msec );

extern  PaError (__cdecl* Pa_GetSampleSize)( PaSampleFormat format );

#endif // __PADLLENTRY_HEADER_INCLUDED__


--- NEW FILE: loadPA_DLL.cpp ---
//////////////////////////////////////////////////////////////////////////


HINSTANCE   pPaDll;

/*
 the function pointers to the PortAudio DLLs
*/

PaError (__cdecl* Pa_Initialize)( void );



PaError (__cdecl* Pa_Terminate)( void );


long (__cdecl* Pa_GetHostError)( void );


const char* (__cdecl* Pa_GetErrorText)( PaError );


int (__cdecl* Pa_CountDevices)(void);

PaDeviceID (__cdecl* Pa_GetDefaultInputDeviceID)( void );

PaDeviceID (__cdecl* Pa_GetDefaultOutputDeviceID)( void );


const PaDeviceInfo* (__cdecl* Pa_GetDeviceInfo)( PaDeviceID);



PaError (__cdecl* Pa_OpenStream)(
    PortAudioStream ** ,
    PaDeviceID ,
    int ,
    PaSampleFormat ,
    void *,
    PaDeviceID ,
    int ,
    PaSampleFormat ,
    void *,
    double ,
    unsigned long ,
    unsigned long ,
    unsigned long ,
    PortAudioCallback *,
    void * );



PaError (__cdecl* Pa_OpenDefaultStream)( PortAudioStream** stream,
        int numInputChannels,
        int numOutputChannels,
        PaSampleFormat sampleFormat,
        double sampleRate,
        unsigned long framesPerBuffer,
        unsigned long numberOfBuffers,
        PortAudioCallback *callback,
        void *userData );


PaError (__cdecl* Pa_CloseStream)( PortAudioStream* );


PaError (__cdecl* Pa_StartStream)( PortAudioStream *stream );

PaError (__cdecl* Pa_StopStream)( PortAudioStream *stream );

PaError (__cdecl* Pa_AbortStream)( PortAudioStream *stream );

PaError (__cdecl* Pa_StreamActive)( PortAudioStream *stream );

PaTimestamp (__cdecl* Pa_StreamTime)( PortAudioStream *stream );

double (__cdecl* Pa_GetCPULoad)( PortAudioStream* stream );

int (__cdecl* Pa_GetMinNumBuffers)( int framesPerBuffer, double sampleRate );

void (__cdecl* Pa_Sleep)( long msec );

PaError (__cdecl* Pa_GetSampleSize)( PaSampleFormat format );


//////////////////////////////////////////////////////////////////////////

...

ZERROR AudioEngine::DirectXSupport(ZBOOL bSupDX)
{
    if (bSupDX)
        if (CheckForDirectXSupport())
            bSupportDirectX = _TRUE;
        else
            return _NO_SOUND;
    else
        bSupportDirectX  = _FALSE;
    return _NO_ERROR;
}



ZBOOL AudioEngine::CheckForDirectXSupport()
{
    HMODULE pTestDXLib;
    FARPROC pFunctionality;

    pTestDXLib=LoadLibrary("DSOUND");
    if (pTestDXLib!=NULL)  // check if there is a DirectSound
    {
        pFunctionality = GetProcAddress(pTestDXLib, (char*) 7);
        if (pFunctionality!=NULL)
        {
            FreeLibrary(pTestDXLib);
            return _TRUE;
        }
        else
        {
            FreeLibrary(pTestDXLib);
            return _FALSE;
        }
    }
    else
        return _FALSE;
}


ZERROR AudioEngine::LoadPALib()
{
#ifdef _DEBUG
    if (bSupportDirectX)
        pPaDll  = LoadLibrary("PA_DXD");
    else
        pPaDll  = LoadLibrary("PA_MMED");
#else
    if (bSupportDirectX)
        pPaDll  = LoadLibrary("PA_DX");
    else
        pPaDll  = LoadLibrary("PA_MME");
#endif
    if (pPaDll!=NULL)
    {

        Pa_Initialize    = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_Initialize");
        Pa_Terminate    = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_Terminate");
        Pa_GetHostError    = (long (__cdecl* )( void )) GetProcAddress(pPaDll,"Pa_GetHostError");
        Pa_GetErrorText    = (const char* (__cdecl* )( PaError )) GetProcAddress(pPaDll,"Pa_GetErrorText");
        Pa_CountDevices    = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_CountDevices");
        Pa_GetDefaultInputDeviceID = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_GetDefaultInputDeviceID");
        Pa_GetDefaultOutputDeviceID = (int (__cdecl*)(void))GetProcAddress(pPaDll,"Pa_GetDefaultOutputDeviceID");
        Pa_GetDeviceInfo   = (const PaDeviceInfo* (__cdecl* )( PaDeviceID)) GetProcAddress(pPaDll,"Pa_GetDeviceInfo");
        Pa_OpenStream    = ( PaError (__cdecl* )(
                                 PortAudioStream ** ,
                                 PaDeviceID ,
                                 int ,
                                 PaSampleFormat ,
                                 void *,
                                 PaDeviceID ,
                                 int ,
                                 PaSampleFormat ,
                                 void *,
                                 double ,
                                 unsigned long ,
                                 unsigned long ,
                                 unsigned long ,
                                 PortAudioCallback *,
                                 void * )) GetProcAddress(pPaDll,"Pa_OpenStream");

        Pa_OpenDefaultStream  = (PaError (__cdecl* )( PortAudioStream** ,
                                 int ,
                                 int ,
                                 PaSampleFormat ,
                                 double ,
                                 unsigned long ,
                                 unsigned long ,
                                 PortAudioCallback *,
                                 void * )) GetProcAddress(pPaDll,"Pa_OpenDefaultStream");
        Pa_CloseStream    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_CloseStream");
        Pa_StartStream    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_StartStream");
        Pa_StopStream    = (PaError (__cdecl* )( PortAudioStream* ))GetProcAddress(pPaDll,"Pa_StopStream");
        Pa_AbortStream    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_AbortStream");
        Pa_StreamActive    = (PaError (__cdecl* )( PortAudioStream* )) GetProcAddress(pPaDll,"Pa_StreamActive");
        Pa_StreamTime    = (PaTimestamp (__cdecl* )( PortAudioStream *))GetProcAddress(pPaDll,"Pa_StreamTime");
        Pa_GetCPULoad    = (double (__cdecl* )( PortAudioStream* ))GetProcAddress(pPaDll,"Pa_GetCPULoad");
        Pa_GetMinNumBuffers   = (int (__cdecl* )( int , double )) GetProcAddress(pPaDll,"Pa_GetMinNumBuffers");
        Pa_Sleep     = (void (__cdecl* )( long )) GetProcAddress(pPaDll,"Pa_Sleep");
        Pa_GetSampleSize   = (PaError (__cdecl* )( PaSampleFormat )) GetProcAddress(pPaDll,"Pa_GetSampleSize");

        return _NO_ERROR;
    }
    else
        return _DLL_NOT_FOUND;
}

ZERROR AudioEngine::UnLoadPALib()
{
    if (pPaDll!=NULL)
        FreeLibrary(pPaDll);
    return _NO_ERROR;
}

...

--- NEW FILE: pa_lib.c ---
/*
 * Portable Audio I/O Library
 * Host Independant Layer
 *
 * Based on the Open Source API proposed by Ross Bencina
 * Copyright (c) 1999-2000 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.
 *
 * 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.
 *
 * 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.
 *
 */

/* Modification History:
 PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */
#ifdef _WIN32
#ifndef __MWERKS__
#include <memory.h>
#endif  /* __MWERKS__ */
#else   /* !_WIN32 */
#include <memory.h>
#endif  /* _WIN32 */

#include "portaudio.h"
#include "pa_host.h"
#include "pa_trace.h"

/* The reason we might NOT want to validate the rate before opening the stream
 * is because many DirectSound drivers lie about the rates they actually support.
 */
#define PA_VALIDATE_RATE    (0)   /* If true validate sample rate against driver info. */

/*
O- maybe not allocate past_InputBuffer and past_OutputBuffer if not needed for conversion
*/

#ifndef FALSE
 #define FALSE  (0)
 #define TRUE   (!FALSE)
#endif

#define PRINT(x) { printf x; fflush(stdout); }
#define ERR_RPT(x) PRINT(x)
#define DBUG(x)  /* PRINT(x) */
#define DBUGX(x) /* PRINT(x) */

static int gInitCount = 0; /* Count number of times Pa_Initialize() called to allow nesting and overlapping. */

static PaError Pa_KillStream(  PortAudioStream *stream, int abort );

/***********************************************************************/
int PaHost_FindClosestTableEntry( double allowableError,  const double *rateTable, int numRates, double frameRate )
{
    double err, minErr = allowableError;
    int i, bestFit = -1;

    for( i=0; i<numRates; i++ )
    {
        err = fabs( frameRate - rateTable[i] );
        if( err < minErr )
        {
            minErr = err;
            bestFit = i;
        }
    }
    return bestFit;
}

/**************************************************************************
** Make sure sample rate is legal and also convert to enumeration for driver.
*/
PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate,
                                   double *closestFrameRatePtr )
{
    long bestRateIndex;
    const PaDeviceInfo *pdi;
    pdi = Pa_GetDeviceInfo( id );
    if( pdi == NULL ) return paInvalidDeviceId;

    if( pdi->numSampleRates == -1 )
    {
        /* Is it out of range? */
        if( (requestedFrameRate < pdi->sampleRates[0]) ||
                (requestedFrameRate > pdi->sampleRates[1]) )
        {
            return paInvalidSampleRate;
        }

        *closestFrameRatePtr = requestedFrameRate;
    }
    else
    {
        bestRateIndex = PaHost_FindClosestTableEntry( 1.0, pdi->sampleRates, pdi->numSampleRates, requestedFrameRate );
        if( bestRateIndex < 0 ) return paInvalidSampleRate;
        *closestFrameRatePtr = pdi->sampleRates[bestRateIndex];
    }
    return paNoError;
}

/*************************************************************************/
DLL_API PaError Pa_OpenStream(
    PortAudioStream** streamPtrPtr,
    PaDeviceID inputDeviceID,
    int numInputChannels,
    PaSampleFormat inputSampleFormat,
    void *inputDriverInfo,
    PaDeviceID outputDeviceID,
    int numOutputChannels,
    PaSampleFormat outputSampleFormat,
    void *outputDriverInfo,
    double sampleRate,
    unsigned long framesPerBuffer,
    unsigned long numberOfBuffers,
    unsigned long streamFlags,
    PortAudioCallback *callback,
    void *userData )
{
    internalPortAudioStream   *past = NULL;
    PaError                    result = paNoError;
    int                        bitsPerInputSample;
    int                        bitsPerOutputSample;
    /* Print passed parameters. */
    DBUG(("Pa_OpenStream( %p, %d, %d, %d, %p, /* input */ \n",
          streamPtrPtr, inputDeviceID, numInputChannels,
          inputSampleFormat, inputDriverInfo ));
    DBUG(("               %d, %d, %d, %p, /* output */\n",
          outputDeviceID, numOutputChannels,
          outputSampleFormat, outputDriverInfo ));
    DBUG(("               %g, %d, %d, 0x%x, , %p )\n",
          sampleRate, framesPerBuffer, numberOfBuffers,
          streamFlags, userData ));

    /* Check for parameter errors. */
    if( (streamFlags & ~(paClipOff | paDitherOff)) != 0 ) return paInvalidFlag;
    if( streamPtrPtr == NULL ) return paBadStreamPtr;
    if( inputDriverInfo != NULL ) return paHostError; /* REVIEW */
    if( outputDriverInfo != NULL ) return paHostError; /* REVIEW */
    if( (inputDeviceID < 0) && ( outputDeviceID < 0) ) return paInvalidDeviceId;
    if( (outputDeviceID >= Pa_CountDevices()) || (inputDeviceID >= Pa_CountDevices()) ) return paInvalidDeviceId;
    if( (numInputChannels <= 0) && ( numOutputChannels <= 0) ) return paInvalidChannelCount;

#if SUPPORT_AUDIO_CAPTURE
    if( inputDeviceID >= 0 )
    {
        PaError size = Pa_GetSampleSize( inputSampleFormat );
        if( size < 0 ) return size;
        bitsPerInputSample = 8 * size;
        if( (numInputChannels <= 0) ) return paInvalidChannelCount;
    }
#else
    if( inputDeviceID >= 0 )
    {
        return paInvalidChannelCount;
    }
#endif /* SUPPORT_AUDIO_CAPTURE */
    else
    {
        if( numInputChannels > 0 ) return paInvalidChannelCount;
        bitsPerInputSample = 0;
    }

    if( outputDeviceID >= 0 )
    {
        PaError size = Pa_GetSampleSize( outputSampleFormat );
        if( size < 0 ) return size;
        bitsPerOutputSample = 8 * size;
        if( (numOutputChannels <= 0) ) return paInvalidChannelCount;
    }
    else
    {
        if( numOutputChannels > 0 ) return paInvalidChannelCount;
        bitsPerOutputSample = 0;
    }

    if( callback == NULL ) return paNullCallback;

    /* Allocate and clear stream structure. */
    past = (internalPortAudioStream *) PaHost_AllocateFastMemory( sizeof(internalPortAudioStream) );
    if( past == NULL ) return paInsufficientMemory;
    memset( past, 0, sizeof(internalPortAudioStream) );
    AddTraceMessage("Pa_OpenStream: past", (long) past );

    past->past_Magic = PA_MAGIC;  /* Set ID to catch bugs. */
    past->past_FramesPerUserBuffer = framesPerBuffer;
    past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */
    past->past_Callback = callback;
    past->past_UserData = userData;
    past->past_OutputSampleFormat = outputSampleFormat;
    past->past_InputSampleFormat = inputSampleFormat;
    past->past_OutputDeviceID = outputDeviceID;
    past->past_InputDeviceID = inputDeviceID;
    past->past_NumInputChannels = numInputChannels;
    past->past_NumOutputChannels = numOutputChannels;
    past->past_Flags = streamFlags;

    /* Check for absurd sample rates. */
    if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
    {
        result = paInvalidSampleRate;
        goto cleanup;
    }

    /* Allocate buffers that may be used for format conversion from user to native buffers. */
    if( numInputChannels > 0 )
    {

#if PA_VALIDATE_RATE
        result = PaHost_ValidateSampleRate( inputDeviceID, sampleRate, &past->past_SampleRate );
        if( result < 0 )
        {
            goto cleanup;
        }
#else
        past->past_SampleRate = sampleRate;
#endif
        /* Allocate single Input buffer. */
        past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8);
        past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize);
        if( past->past_InputBuffer == NULL )
        {
            result = paInsufficientMemory;
            goto cleanup;
        }
    }
    else
    {
        past->past_InputBuffer = NULL;
    }

    /* Allocate single Output buffer. */
    if( numOutputChannels > 0 )
    {
#if PA_VALIDATE_RATE
        result = PaHost_ValidateSampleRate( outputDeviceID, sampleRate, &past->past_SampleRate );
        if( result < 0 )
        {
            goto cleanup;
        }
#else
        past->past_SampleRate = sampleRate;
#endif
        past->past_OutputBufferSize = framesPerBuffer * numOutputChannels * ((bitsPerOutputSample+7) / 8);
        past->past_OutputBuffer = PaHost_AllocateFastMemory(past->past_OutputBufferSize);
        if( past->past_OutputBuffer == NULL )
        {
            result = paInsufficientMemory;
            goto cleanup;
        }
    }
    else
    {
        past->past_OutputBuffer = NULL;
    }

    result = PaHost_OpenStream( past );
    if( result < 0 ) goto cleanup;

    *streamPtrPtr = (void *) past;

    return result;

cleanup:
    if( past != NULL ) Pa_CloseStream( past );
    *streamPtrPtr = NULL;
    return result;
}


/*************************************************************************/
DLL_API PaError Pa_OpenDefaultStream( PortAudioStream** stream,
                                      int numInputChannels,
                                      int numOutputChannels,
                                      PaSampleFormat sampleFormat,
                                      double sampleRate,
                                      unsigned long framesPerBuffer,
                                      unsigned long numberOfBuffers,
                                      PortAudioCallback *callback,
                                      void *userData )
{
    return Pa_OpenStream(
               stream,
               ((numInputChannels > 0) ? Pa_GetDefaultInputDeviceID() : paNoDevice),
               numInputChannels, sampleFormat, NULL,
               ((numOutputChannels > 0) ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
               numOutputChannels, sampleFormat, NULL,
               sampleRate, framesPerBuffer, numberOfBuffers, paNoFlag, callback, userData );
}

/*************************************************************************/
DLL_API PaError Pa_CloseStream( PortAudioStream* stream)
{
    PaError   result;
    internalPortAudioStream   *past;

    DBUG(("Pa_CloseStream()\n"));
    if( stream == NULL ) return paBadStreamPtr;
    past = (internalPortAudioStream *) stream;

    Pa_AbortStream( past );
    result = PaHost_CloseStream( past );

    if( past->past_InputBuffer ) PaHost_FreeFastMemory( past->past_InputBuffer, past->past_InputBufferSize );
    if( past->past_OutputBuffer ) PaHost_FreeFastMemory( past->past_OutputBuffer, past->past_OutputBufferSize );
    PaHost_FreeFastMemory( past, sizeof(internalPortAudioStream) );

    return result;
}

/*************************************************************************/
DLL_API PaError Pa_StartStream( PortAudioStream *stream )
{
    PaError result = paHostError;
    internalPortAudioStream   *past;

    if( stream == NULL ) return paBadStreamPtr;
    past = (internalPortAudioStream *) stream;

    past->past_FrameCount = 0.0;

    if( past->past_NumInputChannels > 0 )
    {
        result = PaHost_StartInput( past );
        DBUG(("Pa_StartStream: PaHost_StartInput returned = 0x%X.\n", result));
        if( result < 0 ) goto error;
    }

    if( past->past_NumOutputChannels > 0 )
    {
        result = PaHost_StartOutput( past );
        DBUG(("Pa_StartStream: PaHost_StartOutput returned = 0x%X.\n", result));
        if( result < 0 ) goto error;
    }

    result = PaHost_StartEngine( past );
    DBUG(("Pa_StartStream: PaHost_StartEngine returned = 0x%X.\n", result));
    if( result < 0 ) goto error;

    return paNoError;

error:
    return result;
}

/*************************************************************************/
DLL_API PaError Pa_StopStream(  PortAudioStream *stream )
{
    return Pa_KillStream( stream, 0 );
}

/*************************************************************************/
DLL_API PaError Pa_AbortStream(  PortAudioStream *stream )
{
    return Pa_KillStream( stream, 1 );
}

/*************************************************************************/
static PaError Pa_KillStream(  PortAudioStream *stream, int abort )
{
    PaError result = paNoError;
    internalPortAudioStream   *past;

    DBUG(("Pa_StopStream().\n"));
    if( stream == NULL ) return paBadStreamPtr;
    past = (internalPortAudioStream *) stream;

    if( (past->past_NumInputChannels > 0) || (past->past_NumOutputChannels > 0) )
    {
        result = PaHost_StopEngine( past, abort );
        DBUG(("Pa_StopStream: PaHost_StopEngine returned = 0x%X.\n", result));
        if( result < 0 ) goto error;
    }

    if( past->past_NumInputChannels > 0 )
    {
        result = PaHost_StopInput( past, abort );
        DBUG(("Pa_StopStream: PaHost_StopInput returned = 0x%X.\n", result));
        if( result != paNoError ) goto error;
    }

    if( past->past_NumOutputChannels > 0 )
    {
        result = PaHost_StopOutput( past, abort );
        DBUG(("Pa_StopStream: PaHost_StopOutput returned = 0x%X.\n", result));
        if( result != paNoError ) goto error;
    }

error:
    past->past_Usage = 0;
    past->past_IfLastExitValid = 0;

    return result;
}

/*************************************************************************/
DLL_API PaError Pa_StreamActive( PortAudioStream *stream )
{
    internalPortAudioStream   *past;
    if( stream == NULL ) return paBadStreamPtr;
    past = (internalPortAudioStream *) stream;
    return PaHost_StreamActive( past );
}

/*************************************************************************/
DLL_API const char *Pa_GetErrorText( PaError errnum )
{
    const char *msg;

    switch(errnum)
    {
    case paNoError:                  msg = "Success"; break;
    case paHostError:                msg = "Host error."; break;
    case paInvalidChannelCount:      msg = "Invalid number of channels."; break;
    case paInvalidSampleRate:        msg = "Invalid sample rate."; break;
    case paInvalidDeviceId:          msg = "Invalid device ID."; break;
    case paInvalidFlag:              msg = "Invalid flag."; break;
    case paSampleFormatNotSupported: msg = "Sample format not supported"; break;
    case paBadIODeviceCombination:   msg = "Illegal combination of I/O devices."; break;
    case paInsufficientMemory:       msg = "Insufficient memory."; break;
    case paBufferTooBig:             msg = "Buffer too big."; break;
    case paBufferTooSmall:           msg = "Buffer too small."; break;
    case paNullCallback:             msg = "No callback routine specified."; break;
    case paBadStreamPtr:             msg = "Invalid stream pointer."; break;
    case paTimedOut    :             msg = "Wait Timed Out."; break;
    case paInternalError:            msg = "Internal PortAudio Error."; break;
    default:                         msg = "Illegal error number."; break;
    }
    return msg;
}

/*
 Get CPU Load as a fraction of total CPU time.
 A value of 0.5 would imply that PortAudio and the sound generating
 callback was consuming roughly 50% of the available CPU time.
 The amount may vary depending on CPU load.
 This function may be called from the callback function.
*/
DLL_API double Pa_GetCPULoad(  PortAudioStream* stream)
{
    internalPortAudioStream   *past;
    if( stream == NULL ) return (double) paBadStreamPtr;
    past = (internalPortAudioStream *) stream;
    return past->past_Usage;
}

/*************************************************************
** Calculate 2 LSB dither signal with a triangular distribution.
** Ranged properly for adding to a 32 bit integer prior to >>15.
*/
#define DITHER_BITS   (15)
#define DITHER_SCALE  (1.0f / ((1<<DITHER_BITS)-1))
static long Pa_TriangularDither( void )
{
    static unsigned long previous = 0;
    static unsigned long randSeed1 = 22222;
    static unsigned long randSeed2 = 5555555;
    long current, highPass;
    /* Generate two random numbers. */
    randSeed1 = (randSeed1 * 196314165) + 907633515;
    randSeed2 = (randSeed2 * 196314165) + 907633515;
    /* Generate triangular distribution about 0. */
    current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS));
    /* High pass filter to reduce audibility. */
    highPass = current - previous;
    previous = current;
    return highPass;
}

/*************************************************************************
** Called by host code.
** Convert input from Int16, call user code, then convert output
** to Int16 format for native use.
** Assumes host native format is paInt16.
** Returns result from user callback.
*/
long Pa_CallConvertInt16( internalPortAudioStream   *past,
                          short *nativeInputBuffer,
                          short *nativeOutputBuffer )
{
    long              temp;
    long              bytesEmpty = 0;
    long              bytesFilled = 0;
    int               userResult;
    unsigned int      i;
    void             *inputBuffer = NULL;
    void             *outputBuffer = NULL;

#if SUPPORT_AUDIO_CAPTURE
    /* Get native data from DirectSound. */
    if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
    {
        /* Convert from native format to PA format. */
        unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels;
        switch(past->past_InputSampleFormat)
        {

        case paFloat32:
            {
                float *inBufPtr = (float *) past->past_InputBuffer;
                inputBuffer = past->past_InputBuffer;
                for( i=0; i<samplesPerBuffer; i++ )
                {
                    inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f);
                }
                break;
            }

        case paInt32:
            {
                /* Convert 16 bit data to 32 bit integers */
                int *inBufPtr = (int *) past->past_InputBuffer;
                inputBuffer = past->past_InputBuffer;
                for( i=0; i<samplesPerBuffer; i++ )
                {
                    inBufPtr[i] = nativeInputBuffer[i] << 16;
                }
                break;
            }

        case paInt16:
            {
                /* Already in correct format so don't copy. */
                inputBuffer = nativeInputBuffer;
                break;
            }

        case paInt8:
            {
                /* Convert 16 bit data to 8 bit chars */
                char *inBufPtr = (char *) past->past_InputBuffer;
                inputBuffer = past->past_InputBuffer;
                if( past->past_Flags & paDitherOff )
                {
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8);
                    }
                }
                else
                {
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        temp = nativeInputBuffer[i];
                        temp += Pa_TriangularDither() >> 7;
                        temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                        inBufPtr[i] = (char)(temp >> 8);
                    }
                }
                break;
            }

        case paUInt8:
            {
                /* Convert 16 bit data to 8 bit unsigned chars */
                unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer;
                inputBuffer = past->past_InputBuffer;
                if( past->past_Flags & paDitherOff )
                {
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80;
                    }
                }
                else
                {
                    /* If you dither then you have to clip because dithering could push the signal out of range! */
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        temp = nativeInputBuffer[i];
                        temp += Pa_TriangularDither() >> 7;
                        temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                        inBufPtr[i] = (unsigned char)(temp + 0x80);
                    }
                }
                break;
            }

        default:
            break;
        }
    }
#endif /* SUPPORT_AUDIO_CAPTURE */

    /* Are we doing output time? */
    if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
    {
        /* May already be in native format so just write directly to native buffer. */
        outputBuffer = (past->past_OutputSampleFormat == paInt16) ?
                       nativeOutputBuffer : past->past_OutputBuffer;
    }
    /*
     AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
     AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
    */
    /* Call user callback routine. */
    userResult = past->past_Callback(
                     inputBuffer,
                     outputBuffer,
                     past->past_FramesPerUserBuffer,
                     past->past_FrameCount,
                     past->past_UserData );

    past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;

    /* Convert to native format if necessary. */
    if( outputBuffer != NULL )
    {
        unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels;
        switch(past->past_OutputSampleFormat)
        {
        case paFloat32:
            {
                float *outBufPtr = (float *) past->past_OutputBuffer;
                if( past->past_Flags & paDitherOff )
                {
                    if( past->past_Flags & paClipOff ) /* NOTHING */
                    {
                        for( i=0; i<samplesPerBuffer; i++ )
                        {
                            *nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f));
                        }
                    }
                    else /* CLIP */
                    {
                        for( i=0; i<samplesPerBuffer; i++ )
                        {
                            temp = (long)(outBufPtr[i] * 32767.0f);
                            *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                        }
                    }
                }
                else
                {
                    /* If you dither then you have to clip because dithering could push the signal out of range! */
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        float dither  = Pa_TriangularDither()*DITHER_SCALE;
                        float dithered = (outBufPtr[i] * (32767.0f)) + dither;
                        temp = (long) (dithered);
                        *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                    }
                }
                break;
            }

        case paInt32:
            {
                int *outBufPtr = (int *) past->past_OutputBuffer;
                if( past->past_Flags & paDitherOff )
                {
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        *nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 );
                    }
                }
                else
                {
                    for( i=0; i<samplesPerBuffer; i++ )
                    {
                        /* Shift one bit down before dithering so that we have room for overflow from add. */
                        temp = (outBufPtr[i] >> 1) + Pa_TriangularDither();
                        temp = temp >> 15;
                        *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp));
                    }
                }
                break;
            }

        case paInt8:
            {
                char *outBufPtr = (char *) past->past_OutputBuffer;
                for( i=0; i<samplesPerBuffer; i++ )
                {
                    *nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8;
                }
                break;
            }

        case paUInt8:
            {
                unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer;
                for( i=0; i<samplesPerBuffer; i++ )
                {
                    *nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8;
                }
                break;
            }

        default:
            break;
        }

    }

    return userResult;
}

/*************************************************************************
** Called by host code.
** Convert input from Float32, call user code, then convert output
** to Float32 format for native use.
** Assumes host native format is Float32.
** Returns result from user callback.
** FIXME - Unimplemented for formats other than paFloat32!!!!
*/
long Pa_CallConvertFloat32( internalPortAudioStream   *past,
                            float *nativeInputBuffer,
                            float *nativeOutputBuffer )
{
    long              bytesEmpty = 0;
    long              bytesFilled = 0;
    int               userResult;
    void             *inputBuffer = NULL;
    void             *outputBuffer = NULL;

    /* Get native data from DirectSound. */
    if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) )
    {
        inputBuffer = nativeInputBuffer;  // FIXME
    }

    /* Are we doing output time? */
    if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) )
    {
        /* May already be in native format so just write directly to native buffer. */
        outputBuffer = (past->past_OutputSampleFormat == paFloat32) ?
                       nativeOutputBuffer : past->past_OutputBuffer;
    }
    /*
     AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer );
     AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer );
    */
    /* Call user callback routine. */
    userResult = past->past_Callback(
                     inputBuffer,
                     outputBuffer,
                     past->past_FramesPerUserBuffer,
                     past->past_FrameCount,
                     past->past_UserData );

    past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer;

    /* Convert to native format if necessary. */ // FIXME
    return userResult;
}

/*************************************************************************/
DLL_API PaError Pa_Initialize( void )
{
    if( gInitCount++ > 0 ) return paNoError;
    ResetTraceMessages();
    return PaHost_Init();
}

DLL_API PaError Pa_Terminate( void )
{
    PaError result = paNoError;

    if( gInitCount == 0 ) return paNoError;
    else if( --gInitCount == 0 )
    {
        result = PaHost_Term();
        DumpTraceMessages();
    }
    return result;
}

/*************************************************************************/
DLL_API PaError Pa_GetSampleSize( PaSampleFormat format )
{
    int size;
    switch(format )
    {

    case paUInt8:
    case paInt8:
        size = 1;
        break;

    case paInt16:
        size = 2;
        break;

    case paPackedInt24:
        size = 3;
        break;

    case paFloat32:
    case paInt32:
    case paInt24:
        size = 4;
        break;

    default:
        size = paSampleFormatNotSupported;
        break;
    }
    return (PaError) size;
}



--- NEW FILE: letter_from_tim_010817.txt ---
From: "Tim Flohrer" <flohrer at zplane.de>
To: "Phil Burk" <philburk at softsynth.com>
Subject: Re: suggestion - multiple backends
Date: Friday, August 17, 2001 7:48 AM

Hi Phil,

here is what I did:

1. I changed the pa_lib.c and portaudio.h in order to provide a dll api 
  if wanted

2. in my application I had a couple of function pointers defined (see 
excerpt loadPA_DLL.cpp) that get their value when the dll is loaded

3. all other files that use the PortAudio-functions had the PaDllEntry.h 
included

I extracted the loadPA_DLL.cpp out of my source so I hope it's 
understandable somehow. If not feel free to ask.

There are also functions for checking if DirectX is available. I am not 
really sure if this is 100% correct, but I noticed that on NT systems it 
is missing the function no. 7 in the dsound.dll so I just check if it's 
there ;O) On the other hand this doesn't tell you if Dsound is emulated 
or not (Dsound gets really bad when emulated, but i suppose you know that).
Hope I didn't forget anything

cheers

tim

--
tim flohrer
flohrer at zplane.de

zplane.development
holsteinische str. 39-42
12161 berlin
  fon: +49.30.854 09 15.0
  fax: +49.30.854 09 15.5
 




More information about the Pd-cvs mailing list