
#include <exec/Semaphores.h>

enum MIDIErrors {MIDI_OK,MIDI_BadTiming,MIDI_NotMIDIFile,MIDI_OutOfMemory};
enum MIDIState {MIDIState_Waiting,MIDIState_Playing,MIDIState_Stopped};

void SP_PlayMIDIFile();
void PlayMIDIFile(void (*SongEndHandler)());
void StopMIDIFile();
BOOL SP_MIDI_Setup();
BOOL MIDI_Setup();
enum MIDIErrors InitMIDIFile(unsigned char *data,ULONG bpm);
                /* if bpm is 0, 125 is used */
void SP_MIDI_Cleanup();
void MIDI_Cleanup();
void SetTempoBPM(ULONG bpm);

/* Please note: You should not directly modify any of the fields within the
   MIDIContext structure  -  Read Only! */

struct MIDIContext
{
  BYTE PlaySignal,StopSignal;
  struct Process *MIDIProcess;
  struct Task *ParentTask;
  void  (*SongEndHandler)();
  enum MIDIState MIDIState;
  unsigned char *TrackData;
  unsigned char *TrackEnd;
  UWORD Division;   /* Normally ticks per quarter note - of the form 3 × 2^n */
  UWORD Tracks;
  UWORD Status;     /* UWORD for neat alignment */
  ULONG Tempo;
  ULONG TickMicroSecs;
  ULONG EClocksPerTick;
  ULONG EClocksPerSecond;
  struct timerequest *TimeReq;
  struct MsgPort *TimeReqPort;
  struct EClockVal EClock;
  struct IOExtSer *SerialReq;
  struct MsgPort *SerialReqPort;
  BOOL SerialPending;
  struct SignalSemaphore DataSemaphore;
  struct SignalSemaphore SubProcSemaphore;
  struct MIDITrackRecord *TrackRecords; /* In preparation for Type 1 support! */
};

struct MIDITrackRecord /* In preparation for Type 1 support! */
{
  LONG DTime;
  unsigned char *TrackStart;
  unsigned char *TrackEnd;
  unsigned char *NextEvent;
  int TrackStatus;
};

extern struct MIDIContext MIDIContext;

struct MThd
{
  ULONG ID;      /* MThd */
  ULONG Length;  /* length of _following_ fields - might be over 6 someday*/
  UWORD Type,Tracks;
  WORD Division;  /* if positive, ticks per quarter note */
};

/* `Status' bytes */
#define ST_NoteOff 128
#define ST_NoteOn 144
#define ST_PolyAT 160
#define ST_Control 176
#define ST_Program 192
#define ST_ChanAT 208
#define ST_PitchBend 224

/* `Meta' Events */
#define EV_Meta 0xFF
#define Meta_EndOfTrack 0x2F
#define Meta_Tempo 0x51

#define EV_SysEx 0xF0
#define EV_SysEx2 0xF7


