#ifndef MIDI_MIDI_H
#define MIDI_MIDI_H

#ifndef EXEC_LISTS_H
 #include <exec/lists.h>
#endif

#ifndef EXEC_PORTS_H
 #include <exec/ports.h>
#endif

/*
    Definitions pertaining to MIDI are derived from MIDI 1.0 Detailed
    Specification (published by the Internation MIDI Association) and is
    current as of 12-Feb-87 except where noted.

    v1.5 - 22-Apr-88
*/


/* midi.library structures & defines */

#define MIDINAME    "midi.library"
#define MIDIVERSION 2L


struct MSource {
    struct Node Node;
    struct Image *Image;
    struct MinList RPList;
    APTR UserData;		/* user data extension */
};

/* node types for Source */
#define NT_MSOURCE	0x20
#define NT_PERMMSOURCE	0x21

struct MDest {
    struct Node Node;
    struct Image *Image;
    struct MinList RPList;
    struct MsgPort *DestPort;
    APTR UserData;		/* user data extension */
};

/* node types for Dest */
#define NT_MDEST	0x22
#define NT_PERMMDEST	0x23


/* Route Stuff */

#define RIM_MAXCOUNT 3

struct RIMatch {
    UBYTE flags;		/* flag bits defined below */
    UBYTE match[RIM_MAXCOUNT];
};

#define RIMF_COUNTBITS 0x03	/* mask for # of match values (0 for match all) */
#define RIMF_EXTID     0x40	/* indicates all 3 bytes of match[] == one 3 byte manuf. id (not valid for CtrlMatch) */
#define RIMF_EXCLUDE   0x80	/* reverses logic of RIMatch so that all except those specified pass */


struct MRouteInfo {
    UWORD MsgFlags;
    UWORD ChanFlags;
    BYTE  ChanOffset;
    BYTE  NoteOffset;
    struct RIMatch SysExMatch;
    struct RIMatch CtrlMatch;
};

/* Msg Flags for MRouteInfo structure and returned by MidiMsgType */

#define MMF_CHAN	0x00ff
#define MMF_NOTEOFF	0x0001
#define MMF_NOTEON	0x0002
#define MMF_POLYPRESS	0x0004
#define MMF_CTRL	0x0008
#define MMF_PROG	0x0010
#define MMF_CHANPRESS	0x0020
#define MMF_PITCHBEND	0x0040
#define MMF_MODE	0x0080

#define MMF_SYSCOM	0x0100
#define MMF_SYSRT	0x0200
#define MMF_SYSEX	0x0400

struct MRoutePtr {
    struct MinNode node;
    struct MRoute *Route;
};

struct MRoute {
    struct MSource *Source;
    struct MDest *Dest;
    struct MRoutePtr SRoutePtr, DRoutePtr;
    struct MRouteInfo RouteInfo;
};



/* MIDI message defininition */

/* Status Bytes */

    /* Channel Voice Messages (1sssnnnn) */
#define MS_NOTEOFF    0x80
#define MS_NOTEON     0x90
#define MS_POLYPRESS  0xA0
#define MS_CTRL       0xB0
#define MS_MODE       0xB0
#define MS_PROG       0xC0
#define MS_CHANPRESS  0xD0
#define MS_PITCHBEND  0xE0

    /* System Common Messages */
#define MS_SYSEX      0xF0
#define MS_QTRFRAME   0xF1
#define MS_SONGPOS    0xF2
#define MS_SONGSELECT 0xF3
#define MS_TUNEREQ    0xF6
#define MS_EOX	      0xF7

    /* System Real Time Messages */
#define MS_CLOCK      0xF8
#define MS_START      0xFA
#define MS_CONTINUE   0xFB
#define MS_STOP       0xFC
#define MS_ACTVSENSE  0xFE
#define MS_RESET      0xFF

/* Note Numbers */

#define MIDDLEC 60


/* Standard Controllers */

    /* continuous 14 bit - MSB: 0-1f, LSB: 20-3f */
#define MC_MODWHEEL  0x01
#define MC_BREATH    0x02
#define MC_FOOT      0x04
#define MC_PORTATIME 0x05
#define MC_DATAENTRY 0x06
#define MC_VOLUME    0x07
#define MC_BALANCE   0x08
#define MC_PAN	     0x0a
#define MC_EXPRESSION 0x0b
#define MC_GENERAL1  0x10
#define MC_GENERAL2  0x11
#define MC_GENERAL3  0x12
#define MC_GENERAL4  0x13

    /* continuous 7 bit (switches: 0-3f=off, 40-7f=on) */
#define MC_SUSTAIN   0x40
#define MC_PORTA     0x41
#define MC_SUSTENUTO 0x42
#define MC_SOFTPEDAL 0x43
#define MC_HOLD2     0x45
#define MC_GENERAL5  0x50
#define MC_GENERAL6  0x51
#define MC_GENERAL7  0x52
#define MC_GENERAL8  0x53
#define MC_TREMOLODEPTH 0x5c
#define MC_CHORUSDEPTH	0x5d
#define MC_CELESTEDEPTH 0x5e
#define MC_PHASERDEPTH	0x5f

    /* parameters */
#define MC_DATAINCR  0x60
#define MC_DATADECR  0x61
#define MC_NRPNL     0x62
#define MC_NRPNH     0x63
#define MC_RPNL      0x64
#define MC_RPNH      0x65


/* Channel Modes */
/* updated from IMA Bulletin V4 06 (July 87) */

#define MM_RESETCTRL 0x79
#define MM_LOCAL     0x7a
#define MM_ALLOFF    0x7b
#define MM_OMNIOFF   0x7c
#define MM_OMNION    0x7d
#define MM_MONO      0x7e
#define MM_POLY      0x7f


/* Registered Parameter Numbers */
/*
    These are 16 bit values that need to be separated into two bytes for
    use with the MC_RPNH & MC_RPNL messages using 8 bit math (hi = MRP_
    >> 8, lo = MRP_ & 0xff) as opposed to 7 bit math.  This is done
    so that the defines match the numbers from the MMA.  See MIDI 1.0
    Detailed Spec p50 for more info.

    updated from IMA Bulletin V4 06 (July 87)
*/

#define MRP_PBSENS	0x0000
#define MRP_FINETUNE	0x0001
#define MRP_COURSETUNE	0x0002


/* Sys/Ex ID numbers */
/*
    Now includes 3 byte extension for North America.  This new format
    uses a 0x00 as the sys/ex id followed by two additional bytes that
    actually identify the manufacturer.  These new extended id constants
    are 16 bit values (as opposed to 14 bit) that you will have to break
    apart yourself (like with the RPN's above).  Again, these are
    defined this way so that they match the MMA's listings.

    The extended id's cannot be used in sys/ex number filtering (since it's
    only designed to handle single byte id's).  You can however use the
    MID_EXTENSION to filter only those manufactures that have one of the
    new id's.

    updated from IMA Bulletin V4 10 (Nov 87)
*/

    /* North America */
#define MID_EXTENSION 0x00
#define MID_SEQUENTIAL 0x01
#define MID_IDP      0x02
#define MID_OCTAVEPLATEAU 0x03
#define MID_MOOG     0x04
#define MID_PASSPORT 0x05
#define MID_LEXICON  0x06
#define MID_KURZWEIL 0x07
#define MID_FENDER   0x08
#define MID_AKG      0x0a
#define MID_VOYCE    0x0b
#define MID_WAVEFRAME 0x0c
#define MID_ADA      0x0d
#define MID_GARFIELD 0x0e
#define MID_ENSONIQ  0x0f
#define MID_OBERHEIM 0x10
#define MID_APPLE    0x11
#define MID_GREYMATTER 0x12
#define MID_PALMTREE 0x14
#define MID_JLCOOPER 0x15
#define MID_LOWREY   0x16
#define MID_ADAMSSMITH 0x17
#define MID_EMU      0x18
#define MID_HARMONY  0x19
#define MID_ART      0x1a
#define MID_BALDWIN  0x1b
#define MID_EVENTIDE 0x1c
#define MID_INVENTRONICS 0x1d
#define MID_CLARITY  0x1f

#define MIDX_PERFECTFRET 0x0014

    /* Europe */
#define MID_SIEL     0x21
#define MID_SYNTHAXE 0x22
#define MID_STEPP    0x23
#define MID_HOHNER   0x24
#define MID_TWISTER  0x25
#define MID_SOLTON   0x26
#define MID_JELLINGHAUS 0x27
#define MID_SOUTHWORTH 0x28
#define MID_PPG      0x29
#define MID_JEN      0x2a
#define MID_SSL      0x2b
#define MID_AUDIOVERITRIEB 0x2c
#define MID_ELKA     0x2f
#define MID_DYNACORD 0x30

    /* Japan */
#define MID_KAWAI    0x40
#define MID_ROLAND   0x41
#define MID_KORG     0x42
#define MID_YAMAHA   0x43
#define MID_CASIO    0x44
#define MID_KAMIYA   0x46
#define MID_AKAI     0x47
#define MID_JAPANVICTOR 0x48
#define MID_MESOSHA  0x49

/* special Sys/Ex ID numbers: Non-Commercial, Non-Real Time, Real Time */
#define MID_NC	0x7d
#define MID_NRT 0x7e
#define MID_RT	0x7f


/* handy macros */

    /* pack high/low bytes of a word into midi format (7/14 bit math) */
#define MIDI_HIBYTE(word) ( (word) >> 7 & 0x7f )
#define MIDI_LOBYTE(word) ( (word) & 0x7f )

    /* unpack 2 midi bytes into a word (7/14 bit math) */
#define MIDI_WORD(hi,lo) ( (hi & 0x7f) << 7 | (lo & 0x7f) )


/* midi.library routine declarations */

struct MSource *CreateMSource(), *FindMSource();
struct MDest *CreateMDest(), *FindMDest();
struct MRoute *CreateMRoute(), *MRouteSource(), *MRouteDest(), *MRoutePublic();
UBYTE *GetMidiMsg();
BOOL PutMidiMsg();
ULONG MidiMsgLength(), MidiMsgType();

#endif
