/*
 * C S O U N D
 *
 * An auto-extensible system for making music on computers
 * by means of software alone.
 *
 * Copyright (C) 2001-2005 Michael Gogins, Matt Ingalls, John D. Ramsdell,
 *                         John P. ffitch, Istvan Varga, Victor Lazzarini
 *
 * L I C E N S E
 *
 * This software is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef CSOUND_H
#define CSOUND_H

/** \file
 * \brief Declares the public Csound application programming interface (API).
 * \author John P. ffitch, Michael Gogins, Matt Ingalls, John D. Ramsdell,
 *         Istvan Varga and Victor Lazzarini
 *
 * \b Purposes
 *
 * The purposes of the Csound API are as follows:
 *
 * \li Declare a stable public application programming interface (API)
 *     for Csound in csound.h. This is the only header file that needs
 *     to be #included by users of the Csound API.
 *
 * \li Hide the internal implementation details of Csound from users of
 *     the API, so that development of Csound can proceed without affecting
 *     code that uses the API.
 *
 * \b Users
 *
 * Users of the Csound API fall into two main categories: hosts, and plugins.
 *
 * \li Hosts are applications that use Csound as a software synthesis engine.
 *     Hosts can link with the Csound API either statically or dynamically.
 *
 * \li Plugins are shared libraries loaded by Csound at run time to implement
 *     external opcodes and/or drivers for audio or MIDI input and output.
 *
 * Hosts using the Csound API must #include <csound.h>, and link with the
 * Csound API library. Plugin libraries should #include <csdl.h> to get
 * access to the API function pointers in the CSOUND structure, and do not
 * need to link with the Csound API library.
 * Only one of csound.h and csdl.h may be included by a compilation unit.
 *
 * Hosts must first create an instance of Csound using the \c csoundCreate
 * API function. When hosts are finished using Csound, they must destroy the
 * instance of csound using the \c csoundDestroy API function.
 * Most of the other Csound API functions take the Csound instance as their
 * first argument.
 * Hosts can only call the standalone API functions declared in csound.h.
 *
 * Here is the complete code for the simplest possible Csound API host,
 * a command-line Csound application:
 *
 * \code
 *
 * #include <csound.h>
 *
 * int main(int argc, char **argv)
 * {
 *     CSOUND *csound = csoundCreate(NULL);
 *     int result = csoundCompile(csound, argc, argv);
 *     if (!result)
 *       result = csoundPerform(csound);
 *     csoundDestroy(csound);
 *     return (result >= 0 ? 0 : result);
 * }
 *
 * \endcode
 *
 * All opcodes, including plugins, receive a pointer to their host
 * instance of Csound as the first argument. Therefore, plugins MUST NOT
 * compile, perform, or destroy the host instance of Csound, and MUST call
 * the Csound API function pointers off the Csound instance pointer.
 *
 * \code
 * MYFLT sr = csound->GetSr(csound);
 * \endcode
 *
 * In general, plugins should ONLY access Csound functionality through the
 * API function pointers and public members of the CSOUND structure.
 */

  /*
   * Platform-dependent definitions and declarations.
   */

#if (defined(WIN32) || defined(_WIN32)) && !defined(SWIG)
#  define PUBLIC        __declspec(dllexport)
#else
#  define PUBLIC
#endif

  /**
   * Enables Python interface.
   */

#ifdef SWIG
#define CS_PRINTF2
#define CS_PRINTF3
#ifndef __MYFLT_DEF
#define __MYFLT_DEF
#ifndef USE_DOUBLE
#define MYFLT float
#else
#define MYFLT double
#endif
#endif
%module csnd
%{
#  include "sysdep.h"
#  include "text.h"
#  include <stdarg.h>
%}
#else
#  include "sysdep.h"
#  include "text.h"
#  include <stdarg.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

  /**
   * ERROR DEFINITIONS
   */

  typedef enum
    {
      /* Completed successfully. */
      CSOUND_SUCCESS = 0,
      /* Unspecified failure. */
      CSOUND_ERROR = -1,
      /* Failed during initialization. */
      CSOUND_INITIALIZATION = -2,
      /* Failed during performance. */
      CSOUND_PERFORMANCE = -3,
      /* Failed to allocate requested memory. */
      CSOUND_MEMORY = -4,
      /* Termination requested by SIGINT or SIGTERM. */
      CSOUND_SIGNAL = -5
    }
  CSOUND_STATUS;

  /* Compilation or performance aborted, but not as a result of an error
     (e.g. --help, or running an utility with -U). */
#define CSOUND_EXITJMP_SUCCESS  (256)

  /**
   * Flags for csoundInitialize().
   */
#define CSOUNDINIT_NO_SIGNAL_HANDLER  1
#define CSOUNDINIT_NO_ATEXIT          2

  /**
   * Constants used by the bus interface (csoundGetChannelPtr() etc.).
   */
#define CSOUND_CONTROL_CHANNEL      1
#define CSOUND_AUDIO_CHANNEL        2
#define CSOUND_STRING_CHANNEL       3

#define CSOUND_CHANNEL_TYPE_MASK    15

#define CSOUND_INPUT_CHANNEL        16
#define CSOUND_OUTPUT_CHANNEL       32

#define CSOUND_CONTROL_CHANNEL_INT  1
#define CSOUND_CONTROL_CHANNEL_LIN  2
#define CSOUND_CONTROL_CHANNEL_EXP  3

#define CSOUND_CALLBACK_KBD_EVENT   (0x00000001U)
#define CSOUND_CALLBACK_KBD_TEXT    (0x00000002U)

  /** 
   * The following constants are used with csound->FileOpen2() and
   * csound->ldmemfile2() to specify the format of a file that is being
   * opened.  This information is passed by Csound to a host's FileOpen
   * callback and does not influence the opening operation in any other
   * way. Conversion from Csound's TYP_XXX macros for audio formats to
   * CSOUND_FILETYPES values can be done with csound->type2csfiletype().
   */
typedef enum
{
    CSFTYPE_UNIFIED_CSD = 1,   /* Unified Csound document */
    CSFTYPE_ORCHESTRA = 2,     /* the primary orc file (may be temporary) */
    CSFTYPE_SCORE = 3,         /* the primary sco file (may be temporary) 
                                  or any additional score opened by Cscore */
    CSFTYPE_ORC_INCLUDE = 4,   /* a file #included by the orchestra */
    CSFTYPE_SCO_INCLUDE = 5,   /* a file #included by the score */
    CSFTYPE_SCORE_OUT = 6,     /* used for score.srt, score.xtr, cscore.out */
    CSFTYPE_SCOT = 7,          /* Scot score input format */
    CSFTYPE_OPTIONS = 8,       /* for .csoundrc and -@ flag */
    CSFTYPE_EXTRACT_PARMS = 9, /* extraction file specified by -x */
    
    /* audio file types that Csound can write (10-19) or read */
    CSFTYPE_RAW_AUDIO = 10,
    CSFTYPE_IRCAM = 11,
    CSFTYPE_AIFF = 12,
    CSFTYPE_AIFC = 13,
    CSFTYPE_WAVE = 14,
    CSFTYPE_AU = 15,
    CSFTYPE_SD2 = 16,
    CSFTYPE_W64 = 17,
    CSFTYPE_WAVEX = 18,
    CSFTYPE_FLAC = 19,
    CSFTYPE_CAF = 20,
    CSFTYPE_AVR = 21,
    CSFTYPE_HTK = 22,
    CSFTYPE_MAT4 = 23,
    CSFTYPE_MAT5 = 24,
    CSFTYPE_NIST = 25,
    CSFTYPE_PAF = 26,
    CSFTYPE_PVF = 27,
    CSFTYPE_SDS = 28,
    CSFTYPE_SVX = 29,
    CSFTYPE_VOC = 30,
    CSFTYPE_XI = 31,
    CSFTYPE_UNKNOWN_AUDIO = 32, /* used when opening audio file for reading
                                   or temp file written with <CsSampleB> */
    
    /* miscellaneous music formats */
    CSFTYPE_SOUNDFONT = 33,
    CSFTYPE_STD_MIDI = 34,     /* Standard MIDI file */
    CSFTYPE_MIDI_SYSEX = 35,   /* Raw MIDI codes, eg. SysEx dump */
    
    /* analysis formats */
    CSFTYPE_HETRO = 36,
    CSFTYPE_PVC = 37,          /* original PVOC format */
    CSFTYPE_PVCEX = 38,        /* PVOC-EX format */
    CSFTYPE_CVANAL = 39,
    CSFTYPE_LPC = 40,
    CSFTYPE_ATS = 41,
    CSFTYPE_LORIS = 42,
    CSFTYPE_SDIF = 43,
    CSFTYPE_HRTF = 44,

    /* Types for plugins and the files they read/write */
    CSFTYPE_VST_PLUGIN = 45,
    CSFTYPE_LADSPA_PLUGIN = 46,
    CSFTYPE_SNAPSHOT = 47,
    
    /* Special formats for Csound ftables or scanned synthesis 
       matrices with header info */
    CSFTYPE_FTABLES_TEXT = 48,   /* for ftsave and ftload  */
    CSFTYPE_FTABLES_BINARY = 49, /* for ftsave and ftload  */
    CSFTYPE_XSCANU_MATRIX = 50,  /* for xscanu opcode  */
    
    /* These are for raw lists of numbers without header info */
    CSFTYPE_FLOATS_TEXT = 51,    /* used by GEN23, GEN28, dumpk, readk */
    CSFTYPE_FLOATS_BINARY = 52,  /* used by dumpk, readk, etc. */
    CSFTYPE_INTEGER_TEXT = 53,   /* used by dumpk, readk, etc. */
    CSFTYPE_INTEGER_BINARY = 54, /* used by dumpk, readk, etc. */

    /* For files that don't match any of the above */
    CSFTYPE_POSTSCRIPT = 55,     /* EPS format used by graphs */
    CSFTYPE_SCRIPT_TEXT = 56,    /* executable script files (eg. Python) */
    CSFTYPE_OTHER_TEXT = 57,
    CSFTYPE_OTHER_BINARY = 58,
    
    /* This should only be used internally by the original FileOpen()
       API call or for temp files written with <CsFileB> */
    CSFTYPE_UNKNOWN = 0 
}    
CSOUND_FILETYPES;

  /*
   * TYPE DEFINITIONS
   */

  /*
   * Forward declarations.
   */

  typedef struct CSOUND_  CSOUND;

  typedef struct windat_  WINDAT;
  typedef struct xyindat_ XYINDAT;

  /**
   * Real-time audio parameters structure
   */
  typedef struct {
    /** device name (NULL/empty: default) */
    char    *devName;
    /** device number (0-1023), 1024: default */
    int     devNum;
    /** buffer fragment size (-b) in sample frames */
    int     bufSamp_SW;
    /** total buffer size (-B) in sample frames */
    int     bufSamp_HW;
    /** number of channels */
    int     nChannels;
    /** sample format (AE_SHORT etc.) */
    int     sampleFormat;
    /** sample rate in Hz */
    float   sampleRate;
  } csRtAudioParams;

  typedef struct RTCLOCK_S {
    int_least64_t   starttime_real;
    int_least64_t   starttime_CPU;
  } RTCLOCK;

  typedef struct {
    char        *opname;
    char        *outypes;
    char        *intypes;
  } opcodeListEntry;

  typedef struct CsoundRandMTState_ {
    int         mti;
    uint32_t    mt[624];
  } CsoundRandMTState;

  typedef struct CsoundChannelListEntry_ {
    const char  *name;
    int         type;
  } CsoundChannelListEntry;

  /* PVSDATEX is a variation on PVSDAT used in
     the pvs bus interface */
  typedef struct pvsdat_ext {
        long            N;
        long            overlap;
        long            winsize;
        int             wintype;
        long            format;
        unsigned long   framecount;
        float*           frame;
 } PVSDATEXT;


  typedef void (*CsoundChannelIOCallback_t)(CSOUND *csound,
                                            const char *channelName,
                                            MYFLT *channelValuePtr,
                                            int channelType);
#ifndef CSOUND_CSDL_H

/* This pragma must come before all public function declarations */
#if (defined(macintosh) && defined(__MWERKS__))
#  pragma export on
#endif

  /*
   * INSTANTIATION
   */

  /**
   * Initialise Csound library; should be called once before creating
   * any Csound instances.
   * Return value is zero on success, positive if initialisation was
   * done already, and negative on error.
   */
  PUBLIC int csoundInitialize(int *argc, char ***argv, int flags);

  /**
   * Creates an instance of Csound.
   * Returns an opaque pointer that must be passed to most Csound API functions.
   * The hostData parameter can be NULL, or it can be a pointer to any sort of
   * data; this pointer can be accessed from the Csound instance that is passed
   * to callback routines.
   */
  PUBLIC CSOUND *csoundCreate(void *hostData);

  /**
   * Reset and prepare an instance of Csound for compilation.
   * Returns CSOUND_SUCCESS on success, and CSOUND_ERROR or
   * CSOUND_MEMORY if an error occured.
   */
  PUBLIC int csoundPreCompile(CSOUND *);

  /**
   * csoundInitializeCscore() prepares an instance of Csound for Cscore
   * processing outside of running an orchestra (i.e. "standalone Cscore").
   * It is an alternative to csoundPreCompile(), csoundCompile(), and
   * csoundPerform*() and should not be used with these functions.
   * You must call this function before using the interface in "cscore.h"
   * when you do not wish to compile an orchestra.
   * Pass it the already open FILE* pointers to the input and
   * output score files.
   * It returns CSOUND_SUCCESS on success and CSOUND_INITIALIZATION or other
   * error code if it fails.
   */
  PUBLIC int csoundInitializeCscore(CSOUND *, FILE *insco, FILE *outsco);

  /**
   * Returns a pointer to the requested interface, if available, in the
   * interface argument, and its version number, in the version argument.
   * Returns 0 for success.
   */
  PUBLIC int csoundQueryInterface(const char *name, void **iface, int *version);

  /**
   * Destroys an instance of Csound.
   */
  PUBLIC void csoundDestroy(CSOUND *);

  /**
   * Returns the version number times 1000 (5.00.0 = 5000).
   */
  PUBLIC int csoundGetVersion(void);

  /**
   * Returns the API version number times 100 (1.00 = 100).
   */
  PUBLIC int csoundGetAPIVersion(void);

  /**
   * Returns host data.
   */
  PUBLIC void *csoundGetHostData(CSOUND *);

  /**
   * Sets host data.
   */
  PUBLIC void csoundSetHostData(CSOUND *, void *hostData);

  /**
   * Get pointer to the value of environment variable 'name', searching
   * in this order: local environment of 'csound' (if not NULL), variables
   * set with csoundSetGlobalEnv(), and system environment variables.
   * If 'csound' is not NULL, should be called after csoundPreCompile()
   * or csoundCompile().
   * Return value is NULL if the variable is not set.
   */
  PUBLIC const char *csoundGetEnv(CSOUND *csound, const char *name);

  /**
   * Set the global value of environment variable 'name' to 'value',
   * or delete variable if 'value' is NULL.
   * It is not safe to call this function while any Csound instances
   * are active.
   * Returns zero on success.
   */
  PUBLIC int csoundSetGlobalEnv(const char *name, const char *value);

  /*
   * PERFORMANCE
   */

  /**
   * Compiles Csound input files (such as an orchestra and score)
   * as directed by the supplied command-line arguments,
   * but does not perform them. Returns a non-zero error code on failure.
   * In this (host-driven) mode, the sequence of calls should be as follows:
   * /code
   *       csoundCompile(csound, argc, argv);
   *       while (!csoundPerformBuffer(csound));
   *       csoundCleanup(csound);
   *       csoundReset(csound);
   * /endcode
   */
  PUBLIC int csoundCompile(CSOUND *, int argc, char **argv);

  /**
   * Senses input events and performs audio output until the end of score
   * is reached (positive return value), an error occurs (negative return
   * value), or performance is stopped by calling csoundStop() from another
   * thread (zero return value).
   * Note that csoundCompile must be called first.
   * In the case of zero return value, csoundPerform() can be called again
   * to continue the stopped performance. Otherwise, csoundReset() should be
   * called to clean up after the finished or failed performance.
   */
  PUBLIC int csoundPerform(CSOUND *);

  /**
   * Senses input events, and performs one control sample worth (ksmps) of
   * audio output.
   * Note that csoundCompile must be called first.
   * Returns false during performance, and true when performance is finished.
   * If called until it returns true, will perform an entire score.
   * Enables external software to control the execution of Csound,
   * and to synchronize performance with audio input and output.
   */
  PUBLIC int csoundPerformKsmps(CSOUND *);

  /**
   * Senses input events, and performs one control sample worth (ksmps) of
   * audio output.
   * Note that csoundCompile must be called first.
   * Performs audio whether or not the Csound score has finished.
   * Enables external software to control the execution of Csound,
   * and to synchronize performance with audio input and output.
   */
  PUBLIC int csoundPerformKsmpsAbsolute(CSOUND *);

  /**
   * Performs Csound, sensing real-time and score events
   * and processing one buffer's worth (-b frames) of interleaved audio.
   * Returns a pointer to the new output audio in 'outputAudio'
   * Note that csoundCompile must be called first, then call
   * csoundGetOutputBuffer() and csoundGetInputBuffer() to get the pointer
   * to csound's I/O buffers.
   * Returns false during performance, and true when performance is finished.
   */
  PUBLIC int csoundPerformBuffer(CSOUND *);

  /**
   * Stops a csoundPerform() running in another thread. Note that it is
   * not guaranteed that csoundPerform() has already stopped when this
   * function returns.
   */
  PUBLIC void csoundStop(CSOUND *);

  /**
   * Prints information about the end of a performance, and closes audio
   * and MIDI devices.
   * Note: after calling csoundCleanup(), the operation of the perform
   * functions is undefined.
   */
  PUBLIC int csoundCleanup(CSOUND *);

  /**
   * Resets all internal memory and state in preparation for a new performance.
   * Enables external software to run successive Csound performances
   * without reloading Csound. Implies csoundCleanup(), unless already called.
   */
  PUBLIC void csoundReset(CSOUND *);

  /*
   * ATTRIBUTES
   */

  /**
   * Returns the number of audio sample frames per second.
   */
  PUBLIC MYFLT csoundGetSr(CSOUND *);

  /**
   * Returns the number of control samples per second.
   */
  PUBLIC MYFLT csoundGetKr(CSOUND *);

  /**
   * Returns the number of audio sample frames per control sample.
   */
  PUBLIC int csoundGetKsmps(CSOUND *);

  /**
   * Returns the number of audio output channels.
   */
  PUBLIC int csoundGetNchnls(CSOUND *);

  /**
   * Returns the 0dBFS level of the spin/spout buffers.
   */
  PUBLIC MYFLT csoundGet0dBFS(CSOUND *);

  /**
   * Returns the number of bytes allocated for a string variable
   * (the actual length is one less because of the null character
   * at the end of the string). Should be called after csoundCompile().
   */
  PUBLIC int csoundGetStrVarMaxLen(CSOUND *);

  /**
   * Returns the sample format.
   */
  PUBLIC int csoundGetSampleFormat(CSOUND *);

  /**
   * Returns the size in bytes of a single sample.
   */
  PUBLIC int csoundGetSampleSize(CSOUND *);

  /**
   * Returns the number of samples in Csound's input buffer.
   */
  PUBLIC long csoundGetInputBufferSize(CSOUND *);

  /**
   * Returns the number of samples in Csound's output buffer.
   */
  PUBLIC long csoundGetOutputBufferSize(CSOUND *);

  /**
   * Returns the address of the Csound audio input buffer.
   * Enables external software to write audio into Csound before calling
   * csoundPerformBuffer.
   */
  PUBLIC MYFLT *csoundGetInputBuffer(CSOUND *);

  /**
   * Returns the address of the Csound audio output buffer.
   * Enables external software to read audio from Csound after calling
   * csoundPerformBuffer.
   */
  PUBLIC MYFLT *csoundGetOutputBuffer(CSOUND *);

  /**
   * Returns the address of the Csound audio input working buffer (spin).
   * Enables external software to write audio into Csound before calling
   * csoundPerformKsmps.
   */
  PUBLIC MYFLT *csoundGetSpin(CSOUND *);

  /**
   * Returns the address of the Csound audio output working buffer (spout).
   * Enables external software to read audio from Csound after calling
   * csoundPerformKsmps.
   */
  PUBLIC MYFLT *csoundGetSpout(CSOUND *);

  /**
   * Returns the output sound file name (-o).
   */
  PUBLIC const char *csoundGetOutputFileName(CSOUND *);

  /**
   * Calling this function with a non-zero 'state' value between
   * csoundPreCompile() and csoundCompile() will disable all default
   * handling of sound I/O by the Csound library, allowing the host
   * application to use the spin/spout/input/output buffers directly.
   * If 'bufSize' is greater than zero, the buffer size (-b) will be
   * set to the integer multiple of ksmps that is nearest to the value
   * specified.
   */
  PUBLIC void csoundSetHostImplementedAudioIO(CSOUND *, int state, int bufSize);

  /**
   * Returns the current score time in seconds
   * since the beginning of performance.
   */
  PUBLIC double csoundGetScoreTime(CSOUND *);

  /*
   * SCORE HANDLING
   */

  /**
   * Sets whether Csound score events are performed or not, independently
   * of real-time MIDI events (see csoundSetScorePending()).
   */
  PUBLIC int csoundIsScorePending(CSOUND *);

  /**
   * Sets whether Csound score events are performed or not (real-time
   * events will continue to be performed). Can be used by external software,
   * such as a VST host, to turn off performance of score events (while
   * continuing to perform real-time events), for example to
   * mute a Csound score while working on other tracks of a piece, or
   * to play the Csound instruments live.
   */
  PUBLIC void csoundSetScorePending(CSOUND *, int pending);

  /**
   * Returns the score time beginning at which score events will
   * actually immediately be performed (see csoundSetScoreOffsetSeconds()).
   */
  PUBLIC MYFLT csoundGetScoreOffsetSeconds(CSOUND *);

  /**
   * Csound score events prior to the specified time are not performed, and
   * performance begins immediately at the specified time (real-time events
   * will continue to be performed as they are received).
   * Can be used by external software, such as a VST host,
   * to begin score performance midway through a Csound score,
   * for example to repeat a loop in a sequencer, or to synchronize
   * other events with the Csound score.
   */
  PUBLIC void csoundSetScoreOffsetSeconds(CSOUND *, MYFLT time);

  /**
   * Rewinds a compiled Csound score to the time specified with
   * csoundSetScoreOffsetSeconds().
   */
  PUBLIC void csoundRewindScore(CSOUND *);

  /**
   * Sets an external callback for Cscore processing.
   * Pass NULL to reset to the internal cscore() function (which does nothing).
   * This callback is retained after a csoundReset() call.
   */
  PUBLIC void csoundSetCscoreCallback(CSOUND *,
                                      void (*cscoreCallback_)(CSOUND *));

  /**
   * Sorts score file 'inFile' and writes the result to 'outFile'.
   * The Csound instance should be initialised with csoundPreCompile()
   * before calling this function, and csoundReset() should be called
   * after sorting the score to clean up. On success, zero is returned.
   */
  PUBLIC int csoundScoreSort(CSOUND *, FILE *inFile, FILE *outFile);

  /**
   * Extracts from 'inFile', controlled by 'extractFile', and writes
   * the result to 'outFile'. The Csound instance should be initialised
   * with csoundPreCompile() before calling this function, and csoundReset()
   * should be called after score extraction to clean up.
   * The return value is zero on success.
   */
  PUBLIC int csoundScoreExtract(CSOUND *,
                                FILE *inFile, FILE *outFile, FILE *extractFile);

  /*
   * MESSAGES & TEXT
   */

  /**
   * Displays an informational message.
   */
  PUBLIC CS_PRINTF2 void csoundMessage(CSOUND *, const char *format, ...);

  /**
   * Print message with special attributes (see msg_attr.h for the list of
   * available attributes). With attr=0, csoundMessageS() is identical to
   * csoundMessage().
   */
  PUBLIC CS_PRINTF3 void csoundMessageS(CSOUND *,
                                        int attr, const char *format, ...);

  PUBLIC void csoundMessageV(CSOUND *,
                             int attr, const char *format, va_list args);

  /**
   * Sets a function to be called by Csound to print an informational message.
   */
  PUBLIC void csoundSetMessageCallback(CSOUND *,
                            void (*csoundMessageCallback_)(CSOUND *,
                                                           int attr,
                                                           const char *format,
                                                           va_list valist));

  /**
   * Returns the Csound message level (from 0 to 231).
   */
  PUBLIC int csoundGetMessageLevel(CSOUND *);

  /**
   * Sets the Csound message level (from 0 to 231).
   */
  PUBLIC void csoundSetMessageLevel(CSOUND *, int messageLevel);

  /**
   * Input a NULL-terminated string (as if from a console),
   * used for line events.
   */
  PUBLIC void csoundInputMessage(CSOUND *, const char *message);

  /**
   * Set the ASCII code of the most recent key pressed.
   * This value is used by the 'sensekey' opcode if a callback
   * for returning keyboard events is not set (see csoundSetCallback()).
   */
  PUBLIC void csoundKeyPress(CSOUND *, char c);

  /*
   * CONTROL AND EVENTS
   */

  /**
   * Control values are specified by a 'channelName' string.
   * Note that the 'invalue' & 'outvalue' channels can be specified by
   * either a string or a number.  If a number is specified, it will be
   * converted to a string before making the callbacks to the external
   * software.
   */

  /**
   * Called by external software to set a function for Csound to
   * fetch input control values.  The 'invalue' opcodes will
   * directly call this function. If 'channelName' starts with a
   * '$', then 'invalue' opcode is expecting a C string, to be copied
   * to 'value', with maximum size csoundGetStrVarMaxLen().
   */
  PUBLIC void csoundSetInputValueCallback(CSOUND *,
                            void (*inputValueCalback_)(CSOUND *,
                                                       const char *channelName,
                                                       MYFLT *value));

  /**
   * Called by external software to set a function for Csound to
   * send output control values.  The 'outvalue' opcodes will
   * directly call this function.  If 'channelName' starts with a
   * '$', then the 'outvalue' opcode is sending a string appended
   * to channelName in the format: "$channelName$stringOutput".
   * and 'value' will be the index number into 'channelName' where
   * the stringOutput begins.
   */
  PUBLIC void csoundSetOutputValueCallback(CSOUND *,
                            void (*outputValueCalback_)(CSOUND *,
                                                        const char *channelName,
                                                        MYFLT value));

  /**
   * Send a new score event. 'type' is the score event type ('a', 'i', 'q',
   * 'f', or 'e').
   * 'numFields' is the size of the pFields array.  'pFields' is an array of
   * floats with all the pfields for this event, starting with the p1 value
   * specified in pFields[0].
   */
  PUBLIC int csoundScoreEvent(CSOUND *,
                              char type, const MYFLT *pFields, long numFields);

  /*
   * MIDI
   */

  /**
   * Sets callback for opening real time MIDI input.
   */
  PUBLIC void csoundSetExternalMidiInOpenCallback(CSOUND *,
            int (*func)(CSOUND *, void **userData, const char *devName));

  /**
   * Sets callback for reading from real time MIDI input.
   */
  PUBLIC void csoundSetExternalMidiReadCallback(CSOUND *,
            int (*func)(CSOUND *, void *userData,
                                  unsigned char *buf, int nBytes));

  /**
   * Sets callback for closing real time MIDI input.
   */
  PUBLIC void csoundSetExternalMidiInCloseCallback(CSOUND *,
            int (*func)(CSOUND *, void *userData));

  /**
   * Sets callback for opening real time MIDI output.
   */
  PUBLIC void csoundSetExternalMidiOutOpenCallback(CSOUND *,
            int (*func)(CSOUND *, void **userData, const char *devName));

  /**
   * Sets callback for writing to real time MIDI output.
   */
  PUBLIC void csoundSetExternalMidiWriteCallback(CSOUND *,
            int (*func)(CSOUND *, void *userData,
                                  const unsigned char *buf, int nBytes));

  /**
   * Sets callback for closing real time MIDI output.
   */
  PUBLIC void csoundSetExternalMidiOutCloseCallback(CSOUND *,
            int (*func)(CSOUND *, void *userData));

  /**
   * Sets callback for converting MIDI error codes to strings.
   */
  PUBLIC void csoundSetExternalMidiErrorStringCallback(CSOUND *,
            const char *(*func)(int));

  /*
   * FUNCTION TABLE DISPLAY
   */

  /**
   * Tells Csound whether external graphic table display is supported.
   * Returns the previously set value (initially zero).
   */
  PUBLIC int csoundSetIsGraphable(CSOUND *, int isGraphable);

  /**
   * Called by external software to set Csound's MakeGraph function.
   */
  PUBLIC void csoundSetMakeGraphCallback(CSOUND *,
                            void (*makeGraphCallback_)(CSOUND *,
                                                       WINDAT *windat,
                                                       const char *name));

  /**
   * Called by external software to set Csound's DrawGraph function.
   */
  PUBLIC void csoundSetDrawGraphCallback(CSOUND *,
                            void (*drawGraphCallback_)(CSOUND *,
                                                       WINDAT *windat));

  /**
   * Called by external software to set Csound's KillGraph function.
   */
  PUBLIC void csoundSetKillGraphCallback(CSOUND *,
                            void (*killGraphCallback_)(CSOUND *,
                                                       WINDAT *windat));

  /**
   * Called by external software to set Csound's MakeXYin function.
   */
  PUBLIC void csoundSetMakeXYinCallback(CSOUND *,
                            void (*makeXYinCallback_)(CSOUND *, XYINDAT *,
                                                      MYFLT x, MYFLT y));

  /**
   * Called by external software to set Csound's ReadXYin function.
   */
  PUBLIC void csoundSetReadXYinCallback(CSOUND *,
                            void (*readXYinCallback_)(CSOUND *, XYINDAT *));

  /**
   * Called by external software to set Csound's KillXYin function.
   */
  PUBLIC void csoundSetKillXYinCallback(CSOUND *,
                            void (*killXYinCallback_)(CSOUND *, XYINDAT *));

  /**
   * Called by external software to set Csound's ExitGraph function.
   */
  PUBLIC void csoundSetExitGraphCallback(CSOUND *,
                            int (*exitGraphCallback_)(CSOUND *));

  /*
   * OPCODES
   */

  /**
   * Gets an alphabetically sorted list of all opcodes.
   * Should be called after externals are loaded by csoundCompile().
   * Returns the number of opcodes, or a negative error code on failure.
   * Make sure to call csoundDisposeOpcodeList() when done with the list.
   */
  PUBLIC int csoundNewOpcodeList(CSOUND *, opcodeListEntry **opcodelist);

  /**
   * Releases an opcode list.
   */
  PUBLIC void csoundDisposeOpcodeList(CSOUND *, opcodeListEntry *opcodelist);

  /**
   * Appends an opcode implemented by external software
   * to Csound's internal opcode list.
   * The opcode list is extended by one slot,
   * and the parameters are copied into the new slot.
   * Returns zero on success.
   */
  PUBLIC int csoundAppendOpcode(CSOUND *, const char *opname,
                                int dsblksiz, int thread,
                                const char *outypes, const char *intypes,
                                int (*iopadr)(CSOUND *, void *),
                                int (*kopadr)(CSOUND *, void *),
                                int (*aopadr)(CSOUND *, void *));

  /*
   * MISCELLANEOUS FUNCTIONS
   */

  /**
   * Platform-independent function to load a shared library.
   */
  PUBLIC int csoundOpenLibrary(void **library, const char *libraryPath);

  /**
   * Platform-independent function to unload a shared library.
   */
  PUBLIC int csoundCloseLibrary(void *library);

  /**
   * Platform-independent function to get a symbol address in a shared library.
   */
  PUBLIC void *csoundGetLibrarySymbol(void *library, const char *symbolName);

  /**
   * Called by external software to set a function for checking system
   * events, yielding cpu time for coopertative multitasking, etc.
   * This function is optional. It is often used as a way to 'turn off'
   * Csound, allowing it to exit gracefully. In addition, some operations
   * like utility analysis routines are not reentrant and you should use
   * this function to do any kind of updating during the operation.
   * Returns an 'OK to continue' boolean.
   */
  PUBLIC void csoundSetYieldCallback(CSOUND *, int (*yieldCallback_)(CSOUND *));

  /*
   * REAL-TIME AUDIO PLAY AND RECORD
   */

  /**
   * Sets a function to be called by Csound for opening real-time
   * audio playback.
   */
  PUBLIC void csoundSetPlayopenCallback(CSOUND *,
                            int (*playopen__)(CSOUND *,
                                              const csRtAudioParams *parm));

  /**
   * Sets a function to be called by Csound for performing real-time
   * audio playback.
   */
  PUBLIC void csoundSetRtplayCallback(CSOUND *,
                            void (*rtplay__)(CSOUND *,
                                             const MYFLT *outBuf, int nbytes));

  /**
   * Sets a function to be called by Csound for opening real-time
   * audio recording.
   */
  PUBLIC void csoundSetRecopenCallback(CSOUND *,
                            int (*recopen_)(CSOUND *,
                                            const csRtAudioParams *parm));

  /**
   * Sets a function to be called by Csound for performing real-time
   * audio recording.
   */
  PUBLIC void csoundSetRtrecordCallback(CSOUND *,
                            int (*rtrecord__)(CSOUND *,
                                              MYFLT *inBuf, int nbytes));

  /**
   * Sets a function to be called by Csound for closing real-time
   * audio playback and recording.
   */
  PUBLIC void csoundSetRtcloseCallback(CSOUND *, void (*rtclose__)(CSOUND *));

  /**
   * Returns whether Csound is in debug mode.
   */
  PUBLIC int csoundGetDebug(CSOUND *);

  /**
   * Sets whether Csound is in debug mode.
   */
  PUBLIC void csoundSetDebug(CSOUND *, int debug);

  /**
   * Returns the length of a function table (not including the guard point),
   * or -1 if the table does not exist.
   */
  PUBLIC int csoundTableLength(CSOUND *, int table);

  /**
   * Returns the value of a slot in a function table.
   * The table number and index are assumed to be valid.
   */
  PUBLIC MYFLT csoundTableGet(CSOUND *, int table, int index);

  /**
   * Sets the value of a slot in a function table.
   * The table number and index are assumed to be valid.
   */
  PUBLIC void csoundTableSet(CSOUND *, int table, int index, MYFLT value);

  /**
   * Stores pointer to function table 'tableNum' in *tablePtr,
   * and returns the table length (not including the guard point).
   * If the table does not exist, *tablePtr is set to NULL and
   * -1 is returned.
   */
  PUBLIC int csoundGetTable(CSOUND *, MYFLT **tablePtr, int tableNum);

  /**
   * Creates and starts a new thread of execution.
   * Returns an opaque pointer that represents the thread on success,
   * or NULL for failure.
   * The userdata pointer is passed to the thread routine.
   */
  PUBLIC void *csoundCreateThread(uintptr_t (*threadRoutine)(void *),
                                  void *userdata);

  /**
   * Returns the ID of the currently executing thread,
   * or NULL for failure.
   */
  PUBLIC void *csoundGetCurrentThreadId(void);

  /**
   * Waits until the indicated thread's routine has finished.
   * Returns the value returned by the thread routine.
   */
  PUBLIC uintptr_t csoundJoinThread(void *thread);

  /**
   * Runs an external command with the arguments specified in 'argv'.
   * argv[0] is the name of the program to execute (if not a full path
   * file name, it is searched in the directories defined by the PATH
   * environment variable). The list of arguments should be terminated
   * by a NULL pointer.
   * If 'noWait' is zero, the function waits until the external program
   * finishes, otherwise it returns immediately. In the first case, a
   * non-negative return value is the exit status of the command (0 to
   * 255), otherwise it is the PID of the newly created process.
   * On error, a negative value is returned.
   */
  PUBLIC long csoundRunCommand(const char * const *argv, int noWait);

  /**
   * Creates and returns a monitor object, or NULL if not successful.
   * The object is initially in signaled (notified) state.
   */
  PUBLIC void *csoundCreateThreadLock(void);

  /**
   * Waits on the indicated monitor object for the indicated period.
   * The function returns either when the monitor object is notified,
   * or when the period has elapsed, whichever is sooner; in the first case,
   * zero is returned.
   * If 'milliseconds' is zero and the object is not notified, the function
   * will return immediately with a non-zero status.
   */
  PUBLIC int csoundWaitThreadLock(void *lock, size_t milliseconds);

  /**
   * Waits on the indicated monitor object until it is notified.
   * This function is similar to csoundWaitThreadLock() with an infinite
   * wait time, but may be more efficient.
   */
  PUBLIC void csoundWaitThreadLockNoTimeout(void *lock);

  /**
   * Notifies the indicated monitor object.
   */
  PUBLIC void csoundNotifyThreadLock(void *lock);

  /**
   * Destroys the indicated monitor object.
   */
  PUBLIC void csoundDestroyThreadLock(void *lock);

  /**
   * Creates and returns a mutex object, or NULL if not successful.
   * Mutexes can be faster than the more general purpose monitor objects
   * returned by csoundCreateThreadLock() on some platforms, and can also
   * be recursive, but the result of unlocking a mutex that is owned by
   * another thread or is not locked is undefined.
   * If 'isRecursive' is non-zero, the mutex can be re-locked multiple
   * times by the same thread, requiring an equal number of unlock calls;
   * otherwise, attempting to re-lock the mutex results in undefined
   * behavior.
   * Note: the handles returned by csoundCreateThreadLock() and
   * csoundCreateMutex() are not compatible.
   */
  PUBLIC void *csoundCreateMutex(int isRecursive);

  /**
   * Acquires the indicated mutex object; if it is already in use by
   * another thread, the function waits until the mutex is released by
   * the other thread.
   */
  PUBLIC void csoundLockMutex(void *mutex_);

  /**
   * Acquires the indicated mutex object and returns zero, unless it is
   * already in use by another thread, in which case a non-zero value is
   * returned immediately, rather than waiting until the mutex becomes
   * available.
   * Note: this function may be unimplemented on Windows.
   */
  PUBLIC int csoundLockMutexNoWait(void *mutex_);

  /**
   * Releases the indicated mutex object, which should be owned by
   * the current thread, otherwise the operation of this function is
   * undefined. A recursive mutex needs to be unlocked as many times
   * as it was locked previously.
   */
  PUBLIC void csoundUnlockMutex(void *mutex_);

  /**
   * Destroys the indicated mutex object. Destroying a mutex that
   * is currently owned by a thread results in undefined behavior.
   */
  PUBLIC void csoundDestroyMutex(void *mutex_);


  /**
   * Create a Thread Barrier. Max value parameter should be equal to
   * number of child threads using the barrier plus one for the
   * master thread */

  PUBLIC void *csoundCreateBarrier(unsigned int max);

  /**
   * Destroy a Thread Barrier.
   */
  PUBLIC int csoundDestroyBarrier(void *barrier);

  /**
   * Wait on the thread barrier
   */
  PUBLIC int csoundWaitBarrier(void *barrier);

  /**
   * Waits for at least the specified number of milliseconds,
   * yielding the CPU to other threads.
   */
  PUBLIC void csoundSleep(size_t milliseconds);

  /**
   * Initialise a timer structure.
   */
  PUBLIC void csoundInitTimerStruct(RTCLOCK *);

  /**
   * Return the elapsed real time (in seconds) since the specified timer
   * structure was initialised.
   */
  PUBLIC double csoundGetRealTime(RTCLOCK *);

  /**
   * Return the elapsed CPU time (in seconds) since the specified timer
   * structure was initialised.
   */
  PUBLIC double csoundGetCPUTime(RTCLOCK *);

  /**
   * Return a 32-bit unsigned integer to be used as seed from current time.
   */
  PUBLIC uint32_t csoundGetRandomSeedFromTime(void);

  /**
   * Set language to 'lang_code' (lang_code can be for example
   * CSLANGUAGE_ENGLISH_UK or CSLANGUAGE_FRENCH or many others,
   * see n_getstr.h for the list of languages). This affects all
   * Csound instances running in the address space of the current
   * process. The special language code CSLANGUAGE_DEFAULT can be
   * used to disable translation of messages and free all memory
   * allocated by a previous call to csoundSetLanguage().
   * csoundSetLanguage() loads all files for the selected language
   * from the directory specified by the CSSTRNGS environment
   * variable.
   */
  PUBLIC void csoundSetLanguage(cslanguage_t lang_code);

  /**
   * Translate string 's' to the current language, and return
   * pointer to the translated message. This may be the same as
   * 's' if language was set to CSLANGUAGE_DEFAULT.
   */
  PUBLIC char *csoundLocalizeString(const char *s);

  /**
   * Allocate nbytes bytes of memory that can be accessed later by calling
   * csoundQueryGlobalVariable() with the specified name; the space is
   * cleared to zero.
   * Returns CSOUND_SUCCESS on success, CSOUND_ERROR in case of invalid
   * parameters (zero nbytes, invalid or already used name), or
   * CSOUND_MEMORY if there is not enough memory.
   */
  PUBLIC int csoundCreateGlobalVariable(CSOUND *,
                                        const char *name, size_t nbytes);

  /**
   * Get pointer to space allocated with the name "name".
   * Returns NULL if the specified name is not defined.
   */
  PUBLIC void *csoundQueryGlobalVariable(CSOUND *, const char *name);

  /**
   * This function is the same as csoundQueryGlobalVariable(), except the
   * variable is assumed to exist and no error checking is done.
   * Faster, but may crash or return an invalid pointer if 'name' is
   * not defined.
   */
  PUBLIC void *csoundQueryGlobalVariableNoCheck(CSOUND *, const char *name);

  /**
   * Free memory allocated for "name" and remove "name" from the database.
   * Return value is CSOUND_SUCCESS on success, or CSOUND_ERROR if the name is
   * not defined.
   */
  PUBLIC int csoundDestroyGlobalVariable(CSOUND *, const char *name);

  /**
   * Return the size of MYFLT in bytes.
   */
  PUBLIC int csoundGetSizeOfMYFLT(void);

  /**
   * Return pointer to user data pointer for real time audio input.
   */
  PUBLIC void **csoundGetRtRecordUserData(CSOUND *);

  /**
   * Return pointer to user data pointer for real time audio output.
   */
  PUBLIC void **csoundGetRtPlayUserData(CSOUND *);

  /**
   * Register a function to be called once in every control period
   * by sensevents(). Any number of functions may be registered,
   * and will be called in the order of registration.
   * The callback function takes two arguments: the Csound instance
   * pointer, and the userData pointer as passed to this function.
   * Returns zero on success.
   */
  PUBLIC int csoundRegisterSenseEventCallback(CSOUND *,
                                              void (*func)(CSOUND *, void *),
                                              void *userData);

  /**
   * Run utility with the specified name and command line arguments.
   * Should be called after loading utility plugins with csoundPreCompile();
   * use csoundReset() to clean up after calling this function.
   * Returns zero if the utility was run successfully.
   */
  PUBLIC int csoundRunUtility(CSOUND *, const char *name,
                                        int argc, char **argv);

  /**
   * Returns a NULL terminated list of registered utility names.
   * The caller is responsible for freeing the returned array with
   * csoundDeleteUtilityList(), however, the names should not be
   * changed or freed.
   * The return value may be NULL in case of an error.
   */
  PUBLIC char **csoundListUtilities(CSOUND *);

  /**
   * Releases an utility list previously returned by csoundListUtilities().
   */
  PUBLIC void csoundDeleteUtilityList(CSOUND *, char **lst);

  /**
   * Get utility description.
   * Returns NULL if the utility was not found, or it has no description,
   * or an error occured.
   */
  PUBLIC const char *csoundGetUtilityDescription(CSOUND *,
                                                 const char *utilName);

  /**
   * Stores a pointer to the specified channel of the bus in *p,
   * creating the channel first if it does not exist yet.
   * 'type' must be the bitwise OR of exactly one of the following values,
   *   CSOUND_CONTROL_CHANNEL
   *     control data (one MYFLT value)
   *   CSOUND_AUDIO_CHANNEL
   *     audio data (csoundGetKsmps(csound) MYFLT values)
   *   CSOUND_STRING_CHANNEL
   *     string data (MYFLT values with enough space to store
   *     csoundGetStrVarMaxLen(csound) characters, including the
   *     NULL character at the end of the string)
   * and at least one of these:
   *   CSOUND_INPUT_CHANNEL
   *   CSOUND_OUTPUT_CHANNEL
   * If the channel already exists, it must match the data type (control,
   * audio, or string), however, the input/output bits are OR'd with the
   * new value. Note that audio and string channels can only be created
   * after calling csoundCompile(), because the storage size is not known
   * until then.
   * Return value is zero on success, or a negative error code,
   *   CSOUND_MEMORY  there is not enough memory for allocating the channel
   *   CSOUND_ERROR   the specified name or type is invalid
   * or, if a channel with the same name but incompatible type already exists,
   * the type of the existing channel. In the case of any non-zero return
   * value, *p is set to NULL.
   * Note: to find out the type of a channel without actually creating or
   * changing it, set 'type' to zero, so that the return value will be either
   * the type of the channel, or CSOUND_ERROR if it does not exist.
   */
  PUBLIC int csoundGetChannelPtr(CSOUND *,
                                 MYFLT **p, const char *name, int type);

  /**
   * Returns a list of allocated channels in *lst. A CsoundChannelListEntry
   * structure contains the name and type of a channel, with the type having
   * the same format as in the case of csoundGetChannelPtr().
   * The return value is the number of channels, which may be zero if there
   * are none, or CSOUND_MEMORY if there is not enough memory for allocating
   * the list. In the case of no channels or an error, *lst is set to NULL.
   * Notes: the caller is responsible for freeing the list returned in *lst
   * with csoundDeleteChannelList(). The name pointers may become invalid
   * after calling csoundReset().
   */
  PUBLIC int csoundListChannels(CSOUND *, CsoundChannelListEntry **lst);

  /**
   * Releases a channel list previously returned by csoundListChannels().
   */
  PUBLIC void csoundDeleteChannelList(CSOUND *, CsoundChannelListEntry *lst);

  /**
   * Sets special parameters for a control channel. The parameters are:
   *   type:  must be one of CSOUND_CONTROL_CHANNEL_INT,
   *          CSOUND_CONTROL_CHANNEL_LIN, or CSOUND_CONTROL_CHANNEL_EXP for
   *          integer, linear, or exponential channel data, respectively,
   *          or zero to delete any previously assigned parameter information
   *   dflt:  the control value that is assumed to be the default, should be
   *          greater than or equal to 'min', and less than or equal to 'max'
   *   min:   the minimum value expected; if the control type is exponential,
   *          it must be non-zero
   *   max:   the maximum value expected, should be greater than 'min';
   *          if the control type is exponential, it must be non-zero and
   *          match the sign of 'min'
   * Returns zero on success, or a non-zero error code on failure:
   *   CSOUND_ERROR:  the channel does not exist, is not a control channel,
   *                  or the specified parameters are invalid
   *   CSOUND_MEMORY: could not allocate memory
   */
  PUBLIC int csoundSetControlChannelParams(CSOUND *, const char *name,
                                           int type, MYFLT dflt,
                                           MYFLT min, MYFLT max);

  /**
   * Returns special parameters (assuming there are any) of a control channel,
   * previously set with csoundSetControlChannelParams().
   * If the channel exists, is a control channel, and has the special parameters
   * assigned, then the default, minimum, and maximum value is stored in *dflt,
   * *min, and *max, respectively, and a positive value that is one of
   * CSOUND_CONTROL_CHANNEL_INT, CSOUND_CONTROL_CHANNEL_LIN, and
   * CSOUND_CONTROL_CHANNEL_EXP is returned.
   * In any other case, *dflt, *min, and *max are not changed, and the return
   * value is zero if the channel exists, is a control channel, but has no
   * special parameters set; otherwise, a negative error code is returned.
   */
  PUBLIC int csoundGetControlChannelParams(CSOUND *, const char *name,
                                           MYFLT *dflt, MYFLT *min, MYFLT *max);

  /**
   * Sets callback function to be called by the opcodes 'chnsend' and
   * 'chnrecv'. Should be called between csoundPreCompile() and
   * csoundCompile().
   * The callback function takes the following arguments:
   *   CSOUND *csound
   *     Csound instance pointer
   *   const char *channelName
   *     the channel name
   *   MYFLT *channelValuePtr
   *     pointer to the channel value. Control channels are a single MYFLT
   *     value, while audio channels are an array of csoundGetKsmps(csound)
   *     MYFLT values. In the case of string channels, the pointer should be
   *     cast to char *, and points to a buffer of
   *     csoundGetStrVarMaxLen(csound) bytes
   *   int channelType
   *     bitwise OR of the channel type (CSOUND_CONTROL_CHANNEL,
   *     CSOUND_AUDIO_CHANNEL, or CSOUND_STRING_CHANNEL; use
   *     channelType & CSOUND_CHANNEL_TYPE_MASK to extract the channel
   *     type), and either CSOUND_INPUT_CHANNEL or CSOUND_OUTPUT_CHANNEL
   *     to indicate the direction of the data transfer
   * The callback is not preserved on csoundReset().
   */
  PUBLIC void csoundSetChannelIOCallback(CSOUND *,
                                         CsoundChannelIOCallback_t func);

  /**
   * Simple linear congruential random number generator:
   *   (*seedVal) = (*seedVal) * 742938285 % 2147483647
   * the initial value of *seedVal must be in the range 1 to 2147483646.
   * Returns the next number from the pseudo-random sequence,
   * in the range 1 to 2147483646.
   */
  PUBLIC int csoundRand31(int *seedVal);

  /**
   * Initialise Mersenne Twister (MT19937) random number generator,
   * using 'keyLength' unsigned 32 bit values from 'initKey' as seed.
   * If the array is NULL, the length parameter is used for seeding.
   */
  PUBLIC void csoundSeedRandMT(CsoundRandMTState *p,
                               const uint32_t *initKey, uint32_t keyLength);

  /**
   * Returns next random number from MT19937 generator.
   * The PRNG must be initialised first by calling csoundSeedRandMT().
   */
  PUBLIC uint32_t csoundRandMT(CsoundRandMTState *p);

  /**
   * Sends a MYFLT value to the chani opcode (k-rate) at index 'n'.
   * The bus is automatically extended if 'n' exceeds any previously used
   * index value, clearing new locations to zero.
   * Returns zero on success, CSOUND_ERROR if the index is invalid, and
   * CSOUND_MEMORY if there is not enough memory to extend the bus.
   */
  PUBLIC int csoundChanIKSet(CSOUND *, MYFLT value, int n);

  /**
   * Receives a MYFLT value from the chano opcode (k-rate) at index 'n'.
   * The bus is automatically extended if 'n' exceeds any previously used
   * index value, clearing new locations to zero.
   * Returns zero on success, CSOUND_ERROR if the index is invalid, and
   * CSOUND_MEMORY if there is not enough memory to extend the bus.
   */
  PUBLIC int csoundChanOKGet(CSOUND *, MYFLT *value, int n);

  /**
   * Sends ksmps MYFLT values to the chani opcode (a-rate) at index 'n'.
   * The bus is automatically extended if 'n' exceeds any previously used
   * index value, clearing new locations to zero.
   * Returns zero on success, CSOUND_ERROR if the index is invalid, and
   * CSOUND_MEMORY if there is not enough memory to extend the bus.
   */
  PUBLIC int csoundChanIASet(CSOUND *, const MYFLT *value, int n);

  /**
   * Receives ksmps MYFLT values from the chano opcode (a-rate) at index 'n'.
   * The bus is automatically extended if 'n' exceeds any previously used
   * index value, clearing new locations to zero.
   * Returns zero on success, CSOUND_ERROR if the index is invalid, and
   * CSOUND_MEMORY if there is not enough memory to extend the bus.
   */
  PUBLIC int csoundChanOAGet(CSOUND *, MYFLT *value, int n);

 /**
 * Sends a PVSDATEX fin to the pvsin opcode (f-rate) at index 'n'.
 * The bus is automatically extended if 'n' exceeds any previously used
 * index value, clearing new locations to zero.
 * Returns zero on success, CSOUND_ERROR if the index is invalid or
 * fsig framesizes are incompatible
 * CSOUND_MEMORY if there is not enough memory to extend the bus.
 */
  PUBLIC int csoundPvsinSet(CSOUND *, const PVSDATEXT *fin, int n);

 /**
 * Receives a PVSDAT fout from the pvsout opcode (f-rate) at index 'n'.
 * The bus is extended if 'n' exceeds any previous value.
 * Returns zero on success, CSOUND_ERROR if the index is invalid or
 * if fsig framesizes are incompatible
 * CSOUND_MEMORY if there is not enough memory to extend the bus
 */
  PUBLIC int csoundPvsoutGet(CSOUND *csound, PVSDATEXT *fout, int n);

  /**
   * Sets general purpose callback function that will be called on various
   * events. The callback is preserved on csoundReset(), and multiple
   * callbacks may be set and will be called in reverse order of
   * registration. If the same function is set again, it is only moved
   * in the list of callbacks so that it will be called first, and the
   * user data and type mask parameters are updated. 'typeMask' can be the
   * bitwise OR of callback types for which the function should be called,
   * or zero for all types.
   * Returns zero on success, CSOUND_ERROR if the specified function
   * pointer or type mask is invalid, and CSOUND_MEMORY if there is not
   * enough memory.
   *
   * The callback function takes the following arguments:
   *   void *userData
   *     the "user data" pointer, as specified when setting the callback
   *   void *p
   *     data pointer, depending on the callback type
   *   unsigned int type
   *     callback type, can be one of the following (more may be added in
   *     future versions of Csound):
   *       CSOUND_CALLBACK_KBD_EVENT
   *       CSOUND_CALLBACK_KBD_TEXT
   *         called by the sensekey opcode to fetch key codes. The data
   *         pointer is a pointer to a single value of type 'int', for
   *         returning the key code, which can be in the range 1 to 65535,
   *         or 0 if there is no keyboard event.
   *         For CSOUND_CALLBACK_KBD_EVENT, both key press and release
   *         events should be returned (with 65536 (0x10000) added to the
   *         key code in the latter case) as unshifted ASCII codes.
   *         CSOUND_CALLBACK_KBD_TEXT expects key press events only as the
   *         actual text that is typed.
   * The return value should be zero on success, negative on error, and
   * positive if the callback was ignored (for example because the type is
   * not known).
   */
  PUBLIC int csoundSetCallback(CSOUND *, int (*func)(void *userData, void *p,
                                                     unsigned int type),
                                         void *userData, unsigned int typeMask);

  /**
   * Removes a callback previously set with csoundSetCallback().
   */
  PUBLIC void csoundRemoveCallback(CSOUND *,
                                   int (*func)(void *, void *, unsigned int));
                                   


  /**
   * Creates a buffer for storing messages printed by Csound.
   * Should be called after creating a Csound instance; note that
   * the message buffer uses the host data pointer, and the buffer
   * should be freed by calling csoundDestroyMessageBuffer() before
   * deleting the Csound instance.
   * If 'toStdOut' is non-zero, the messages are also printed to
   * stdout and stderr (depending on the type of the message),
   * in addition to being stored in the buffer.
   */
  void PUBLIC csoundEnableMessageBuffer(CSOUND *csound, int toStdOut);

  /**
   * Returns the first message from the buffer.
   */
  PUBLIC const char*  csoundGetFirstMessage(CSOUND *csound);

  /**
   * Returns the attribute parameter (see msg_attr.h) of the first message
   * in the buffer.
   */
  int PUBLIC csoundGetFirstMessageAttr(CSOUND *csound);

  /**
   * Removes the first message from the buffer.
   */
  void PUBLIC csoundPopFirstMessage(CSOUND *csound);

  /**
   * Returns the number of pending messages in the buffer.
   */
  int PUBLIC csoundGetMessageCnt(CSOUND *csound);

  /**
   * Releases all memory used by the message buffer.
   */
  void PUBLIC csoundDestroyMessageBuffer(CSOUND *csound);

  void PUBLIC sigcpy(MYFLT *dest, MYFLT *src, int size);

#if !defined(SWIG)
  /**
   * Sets an external callback for receiving notices whenever Csound opens
   * a file.  The callback is made after the file is successfully opened.
   * The following information is passed to the callback:
   *     char*  pathname of the file; either full or relative to current dir
   *     int    a file type code from the enumeration CSOUND_FILETYPES
   *     int    1 if Csound is writing the file, 0 if reading
   *     int    1 if a temporary file that Csound will delete; 0 if not
   * 
   * Pass NULL to disable the callback.
   * This callback is retained after a csoundReset() call.
   */
  PUBLIC void csoundSetFileOpenCallback(CSOUND *p,
                           void (*func)(CSOUND*, const char*, int, int, int));
#endif

/* This pragma must come after all public function declarations */
#if (defined(macintosh) && defined(__MWERKS__))
#  pragma export off
#endif

#endif  /* !CSOUND_CSDL_H */

  /* typedefs, macros, and interface functions for configuration variables */
#include "cfgvar.h"
  /* message attribute definitions for csoundMessageS() and csoundMessageV() */
#include "msg_attr.h"
  /* macro definitions for Csound release, and API version */
#include "version.h"

#ifdef __cplusplus
}
#endif

#endif  /* CSOUND_H */

