/*

This software module was originally developed by 

Mike Guzewicz (E-mu Systems)


in the course of development of the MPEG-4 Audio (ISO/IEC 14496-3) standard. 
This software module is an implementation of a part of one or more 
MPEG-4 Audio (ISO/IEC 14496-3) tools as specified by the MPEG-4 Audio 
(ISO/IEC 14496-3). ISO/IEC gives users of the MPEG-4 Audio (ISO/IEC 14496-3) 
free license to this software module or modifications thereof for use 
in hardware or software products claiming conformance to the MPEG-4 Audio 
(ISO/IEC 14496-3). Those intending to use this software module in hardware 
or software products are advised that its use may infringe existing patents. 
The original developer of this software module and his/her company, the 
subsequent editors and their companies, and ISO/IEC have no liability for 
use of this software module or modifications thereof in an implementation. 
Copyright is not released for non MPEG-4 Audio (ISO/IEC 14496-3) conforming 
products. E-mu Systems retains full right to use the code for his/her own 
purpose, assign or donate the code to a third party and to inhibit third 
parties from using the code for non MPEG-4 Audio (ISO/IEC 14496-3) 
conforming products. This copyright notice must be included in all copies 
or derivative works. 

Copyright (C) 1997 E-mu Systems, Inc.

*/

     /*********************************************************************
     
     sfe_datatype.h
     
     
     *********************************************************************/

/*****************************************************************************
* @(#)datatype.h        1.1 12:06:28 3/15/95 12:06:35
*
* Filename: datatype.h
*
* Description: Header file for SoundFont enabler Data Types
*
*******************************************************************************
*/

#ifndef __DATATYPE_H
#define __DATATYPE_H

/************
* Includes
************/

#include <limits.h>


/************
* Defines
************/

#ifndef __BYTE_INCOHERENT    /* Big    Endian  (IE 680x0) */
#define __BYTE_COHERENT      /* Little Endian  (IE 80x86) */
#endif

#ifdef _UNIX_STUB_
#define pascal
#define signed
#endif

#ifdef EMU_WINDOWS
#include <windows.h>
#else
#define _export
#endif

#ifdef __cplusplus
#  define EMUCTYPE extern "C"
#  define BEGINEMUCTYPE EMUCTYPE {
#  define ENDEMUCTYPE   }
#else
#  define EMUCTYPE
#  define BEGINEMUCTYPE
#  define ENDEMUCTYPE
#endif

/* Expected data values */
#define CHAR_MINVAL  -127
#define CHAR_MAXVAL   127
#define BYTE_MAXVAL   255
#define SHRT_MINVAL  -32767
#define SHRT_MAXVAL   32767
#define LONG_MINVAL  -2147483647L
#define LONG_MAXVAL   2147483647L
#define DWORD_MAXVAL  4294967295L

#ifndef FALSE
#define FALSE  0
#endif

#ifndef TRUE
#define TRUE   1
#endif

#ifndef EMU_WINDOWS // windows.h defines these already
#define LOBYTE(x)  ((x) & 0x00FF)
#define HIBYTE(x)  (((x) & 0xFF00) >> 8)
#endif


/*************
* Typedefs
*************/

typedef char                CHAR;      /*  8 bit signed value          */
typedef short               SHORT;     /* 16 bit signed value was: INT */

#ifdef EMU_WINDOWS
  /*****************************************************************
  * These idiosyncratic pointer definitions for memory allocations
  * which are greater than 64K and are Intel-centric compiling
  * environment necessities, at least for Windows environments.
  * Perhaps, however, Windows NT will eliminate the 'huge' keyword
  * requirement altogether.
  *****************************************************************/

  typedef BYTE  huge* BYTEPTR;
  typedef WORD  huge* UINTPTR;
  typedef DWORD huge* DWORDPTR;
  typedef void  huge* VOIDPTR;
#else

#ifndef _AIFIF_H
  typedef unsigned char       BYTE;    /*  8 bit unsigned value   */
#endif

  typedef short               BOOL;    /* 16 bit signed value     */
  typedef unsigned short      WORD;    /* 16 bit signed value     */

#ifdef __alpha

#ifndef _DPWELIB_H_
  typedef signed int          LONG;
#endif
  typedef unsigned int        DWORD;
#else
#ifndef _DPWELIB_H_
  typedef signed long         LONG;    /* 32 bit signed value     */
#endif
  typedef unsigned long       DWORD;   /* 32 bit unsigned value   */
#endif

  typedef float               FLOAT;   /* 32 bit floating point value */
  typedef double              DOUBLE;  /* 64 bit floating point value */
  typedef long double         LDOUBLE; /* 80 bit floating point value */

  typedef BYTE*               BYTEPTR;
  typedef WORD*               UINTPTR;
  typedef DWORD*              DWORDPTR;
  typedef void*               VOIDPTR;
#endif /* EMU_WINDOWS */


/********************************************************************
* This 16 bit unsigned value is used for routines which return
* standard E-mu error codes (see emuerrs.h)
********************************************************************/
typedef unsigned short        EMUSTAT;

/********************************************************************
* Compare <limits.h> values with SoundFont Enabler limits.  Fail compile
* if discrepency. If compile fails due to one of these errors, then
* the SoundFont enabler will not work with your system or the state of your
* development environment.
********************************************************************/
#if (SCHAR_MAX != CHAR_MAXVAL) || (UCHAR_MAX != BYTE_MAXVAL)
#error <datatype.h>: char is out of range!
#endif

#if (SHRT_MAX != SHRT_MAXVAL)
#error <datatype.h>: short is out of range!
#endif

#if 0
#if (LONG_MAX != LONG_MAXVAL)
  #error <datatype.h>: long is out of range!
#endif

#if (ULONG_MAX != DWORD_MAXVAL)
  #error <datatype.h>: unsigned long is out of range!
#endif
#endif

#ifdef __BYTE_COHERENT

/********************************************************************
* Convenient union datatypes to use for byte swapping or extracting
* bytes and/or shorts within a short or long value without using
* bit shifting. 
********************************************************************/
typedef struct twoBytesTag
{
  BYTE by0;
  BYTE by1;
} twoBytes;


typedef struct fourBytesTag
{
  BYTE by0;
  BYTE by1;
  BYTE by2;
  BYTE by3;
} fourBytes;


typedef struct twoWordsTag
{
  WORD w0;
  WORD w1;
} twoWords;

#elif defined(__BYTE_INCOHERENT)

typedef struct twoBytesTag
{
  BYTE by1;
  BYTE by0;
} twoBytes;


typedef struct fourBytesTag
{
  BYTE by3;
  BYTE by2;
  BYTE by1;
  BYTE by0;
} fourBytes;


typedef struct twoWordsTag
{
  WORD w1;
  WORD w0;
} twoWords;

#endif  /*  BYTE COHERENCY  */


typedef union twoByteUnionTag
{
  twoBytes byVals;
  WORD     wVal;
} twoByteUnion;


typedef union fourByteUnionTag  /* make the three 32 bit definitions  */
{                               /* interchangeable                    */
  fourBytes byVals;
  twoWords  wVals;
  DWORD     dwVal;
} fourByteUnion;

   /************************************************************
    * These are the VARIABLES which are used for byte swapping
    ***********************************************************/

#define SWAP_WORD_DECLARATIONS \
  twoByteUnion tbUnion;        \
  twoByteUnion *ptbUnion;
  
#define SWAP_DWORD_DECLARATIONS \
  fourByteUnion fbUnion;        \
  fourByteUnion *pfbUnion;
  
   /************************************************************
    * These are the GENERIC byte software macros. Note they use
    * the variables defined above!
    ***********************************************************/

#define SWAP_WORD(wValue)                               \
{                                                       \
  tbUnion.wVal            = wValue;                     \
  ptbUnion                = (twoByteUnion *)((WORD *)(&(wValue)));\
  ptbUnion->byVals.by0    = tbUnion.byVals.by1;         \
  ptbUnion->byVals.by1    = tbUnion.byVals.by0;         \
}

#define SWAP_DWORD(dwValue)                            \
{                                                      \
  fbUnion.dwVal        = dwValue;                      \
  pfbUnion             = (fourByteUnion *)((DWORD *)(&(dwValue)));\
  pfbUnion->byVals.by0 = fbUnion.byVals.by3;           \
  pfbUnion->byVals.by1 = fbUnion.byVals.by2;           \
  pfbUnion->byVals.by2 = fbUnion.byVals.by1;           \
  pfbUnion->byVals.by3 = fbUnion.byVals.by0;           \
}

   /************************************************************
    * These are DEFINES to allow one to have byte swapping
    * routines exist or not exist based on ENDIAN NATURE.
    * (IE byte swap ONLY if LITTLE ENDIAN system).
    ***********************************************************/

   /********************************************************************
    * Byte Coherent (little endian) specific byte swapping methods 
    *******************************************************************/
#ifdef __BYTE_COHERENT

/* For little endian systems, the BIG ENDIAN methods are NOT defined */
#define SWAP_WORD_BYTE_INCOH_DECLARATIONS 
#define SWAP_DWORD_BYTE_INCOH_DECLARATIONS
#define SWAP_WORD_BYTE_INCOH_ONLY(a) 
#define SWAP_DWORD_BYTE_INCOH_ONLY(a) 

/* For little endian systems, the LITTLE ENDIAN methods are defined as the
   generic methods */
#define SWAP_WORD_BYTE_COH_DECLARATIONS  SWAP_WORD_DECLARATIONS  
#define SWAP_DWORD_BYTE_COH_DECLARATIONS  SWAP_DWORD_DECLARATIONS
#define SWAP_WORD_BYTE_COH_ONLY(a) SWAP_WORD(a)
#define SWAP_DWORD_BYTE_COH_ONLY(a) SWAP_DWORD(a)


   /********************************************************************
    * Byte Incoherent (big endian) specific byte swapping methods 
    *******************************************************************/
#elif defined (__BYTE_INCOHERENT)

/* For big endian systems, the BIG ENDIAN methods are defined as the
   generic methods */
#define SWAP_WORD_BYTE_INCOH_DECLARATIONS SWAP_WORD_DECLARATIONS
#define SWAP_DWORD_BYTE_INCOH_DECLARATIONS SWAP_DWORD_DECLARATIONS
#define SWAP_WORD_BYTE_INCOH_ONLY(a) SWAP_WORD(a)
#define SWAP_DWORD_BYTE_INCOH_ONLY(a) SWAP_DWORD(a)

/* For big endian systems, the LITTLE ENDIAN methods are NOT defined */
#define SWAP_WORD_BYTE_COH_DECLARATIONS
#define SWAP_DWORD_BYTE_COH_DECLARATIONS
#define SWAP_WORD_BYTE_COH_ONLY(a)
#define SWAP_DWORD_BYTE_COH_ONLY(a)

#endif

#endif /* __DATATYPE_H */
