#ifndef PA_UTIL_H
#define PA_UTIL_H
/*
 * $Id$
 * Portable Audio I/O Library implementation utilities header
 * common implementation utilities and interfaces
 *
 * Based on the Open Source API proposed by Ross Bencina
 * Copyright (c) 1999-2008 Ross Bencina, 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 common_src

    @brief Prototypes for utility functions used by PortAudio implementations.

    Some functions declared here are defined in pa_front.c while others
    are implemented separately for each platform.
*/


#include "portaudio.h"

/** Preprocessor Utilities
*/

#define PA_STRINGIZE_HELPER(x) #x
#define PA_STRINGIZE(x) PA_STRINGIZE_HELPER(x)


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


struct PaUtilHostApiRepresentation;


/** Retrieve a specific host API representation. This function can be used
 by implementations to retrieve a pointer to their representation in
 host api specific extension functions which aren't passed a rep pointer
 by pa_front.c.

 @param hostApi A pointer to a host API representation pointer. Upon success
 this will receive the requested representation pointer.

 @param type A valid host API type identifier.

 @returns An error code. If the result is PaNoError then a pointer to the
 requested host API representation will be stored in *hostApi. If the host API
 specified by type is not found, this function returns paHostApiNotFound.
*/
PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
        PaHostApiTypeId type );


/** Convert a PortAudio device index into a host API specific device index.
 @param hostApiDevice Pointer to a device index, on success this will receive the
 converted device index value.
 @param device The PortAudio device index to convert.
 @param hostApi The host api which the index should be converted for.

 @returns On success returns PaNoError and places the converted index in the
 hostApiDevice parameter.
*/
PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
        PaDeviceIndex *hostApiDevice, PaDeviceIndex device,
        struct PaUtilHostApiRepresentation *hostApi );


/** Set the host error information returned by Pa_GetLastHostErrorInfo. This
 function and the paUnanticipatedHostError error code should be used as a
 last resort.  Implementors should use existing PA error codes where possible,
 or nominate new ones. Note that at it is always better to use
 PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an
 ambiguous or inaccurate PaError code.

 @param hostApiType  The host API which encountered the error (ie of the caller)

 @param errorCode The error code returned by the native API function.

 @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo
 makes a copy of the string, so it is not necessary for the pointer to remain
 valid after the call to PaUtil_SetLastHostErrorInfo() returns.

*/
void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
        const char *errorText );



/* the following functions are implemented in a platform platform specific
 .c file
*/

/** Allocate size bytes of zero-initialized memory.
Guaranteed to be aligned to a FIXME byte boundary.
*/
void *PaUtil_AllocateZeroInitializedMemory( long size );


/** Release block allocated by PaUtil_AllocateZeroInitializedMemory()
if block is non-NULL. block may be NULL */
void PaUtil_FreeMemory( void *block );


/** Return the number of currently allocated blocks. This function can be
 used for detecting memory leaks.

 @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If
 it isn't, this function will always return 0.
*/
int PaUtil_CountCurrentlyAllocatedBlocks( void );


/** Initialize the clock used by PaUtil_GetTime(). Call this before calling
 PaUtil_GetTime.

 @see PaUtil_GetTime
*/
void PaUtil_InitializeClock( void );


/** Return the system time in seconds. Used to implement CPU load functions

 @note Do not make assumptions about which underlying clock is used to implement
  PaUtil_GetTime, or use the current implementation as a guide. Do not use this
  function when a specific clock is required (e.g. when using platform APIs
  such as pthreads). If you need to use a specific clock, use a native API that
  returns that clock.

 @see PaUtil_InitializeClock
*/
double PaUtil_GetTime( void );


/* void Pa_Sleep( long msec );  must also be implemented in per-platform .c file */



#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* PA_UTIL_H */
