/***********************************************************************
 Copyright © 1995 - 1998, 3Com Corporation or its subsidiaries ("3Com").  
 All rights reserved.
   
 This software may be copied and used solely for developing products for 
 the Palm Computing platform and for archival and backup purposes.  Except 
 for the foregoing, no part of this software may be reproduced or transmitted 
 in any form or by any means or used to make any derivative work (such as 
 translation, transformation or adaptation) without express written consent 
 from 3Com.

 3Com reserves the right to revise this software and to make changes in content 
 from time to time without obligation on the part of 3Com to provide notification 
 of such revision or changes.  
 3COM MAKES NO REPRESENTATIONS OR WARRANTIES THAT THE SOFTWARE IS FREE OF ERRORS 
 OR THAT THE SOFTWARE IS SUITABLE FOR YOUR USE.  THE SOFTWARE IS PROVIDED ON AN 
 "AS IS" BASIS.  3COM MAKES NO WARRANTIES, TERMS OR CONDITIONS, EXPRESS OR IMPLIED, 
 EITHER IN FACT OR BY OPERATION OF LAW, STATUTORY OR OTHERWISE, INCLUDING WARRANTIES, 
 TERMS, OR CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND 
 SATISFACTORY QUALITY.

 TO THE FULL EXTENT ALLOWED BY LAW, 3COM ALSO EXCLUDES FOR ITSELF AND ITS SUPPLIERS 
 ANY LIABILITY, WHETHER BASED IN CONTRACT OR TORT (INCLUDING NEGLIGENCE), FOR 
 DIRECT, INCIDENTAL, CONSEQUENTIAL, INDIRECT, SPECIAL, OR PUNITIVE DAMAGES OF 
 ANY KIND, OR FOR LOSS OF REVENUE OR PROFITS, LOSS OF BUSINESS, LOSS OF INFORMATION 
 OR DATA, OR OTHER FINANCIAL LOSS ARISING OUT OF OR IN CONNECTION WITH THIS SOFTWARE, 
 EVEN IF 3COM HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

 3Com, HotSync, Palm Computing, and Graffiti are registered trademarks, and 
 Palm III and Palm OS are trademarks of 3Com Corporation or its subsidiaries.

 IF THIS SOFTWARE IS PROVIDED ON A COMPACT DISK, THE OTHER SOFTWARE AND 
 DOCUMENTATION ON THE COMPACT DISK ARE SUBJECT TO THE LICENSE AGREEMENT 
 ACCOMPANYING THE COMPACT DISK.

 ***************************************************************************
 *
 *		PROJECT:		Rocky
 * 	FILE:     	MidiPrv.h
 * 	AUTHOR:		Vitaly M. Kruglikov
 *		DATE:			August 1, 1997
 *
 * 	DECLARER: 	MIDI Parser
 *
 * 	DESCRIPTION:	Private MIDI and SMF (Standard MIDI File) implementation declarations
 *
 *	REVISION HISTORY:
 *		Name	Date			Description
 *		----	----			-----------
 *		vmk	8/1/1997		Created
 *
 **********************************************************************/


#ifndef __MIDI_H__
#define __MIDI_H__



// SMF chunk types (ASCII)
#define midiSmfHeaderChunkType	'MThd'		// SMF Header Chunk
#define midiSmfTrackChunkType		'MTrk'		// SMF Track Chunk


// SMF file formats
#define	midiSmfFmt0				(0)
#define	midiSmfFmt1				(1)
#define	midiSmfFmt2				(2)
#define	midiSmfFmtUnknown		(0xFFFF)

#define midiSmfMaxValidFmt		midiSmfFmt2


// SMPTE time code division formats
#define midiSmfNegSMPTEFmt24				(-24)
#define midiSmfNegSMPTEFmt25				(-25)
#define midiSmfNegSMPTEFmt30Drop			(-29)
#define midiSmfNegSMPTEFmt30NonDrop		(-30)


// MIDI Message Status values
#define midiMsgStatusNone		(0)				// no  status
#define midiMaxChanMsgStatus	(0xEF)			// maximum MIDI channel message status value
#define midiMsgBaseNoteOff		(0x080)			// note off
#define midiMsgBaseNoteOn		(0x090)			// note on
#define midiMsgBasePolyPress	(0x0A0)			// poliphonic key pressure (aftertouch)
#define midiMsgBaseCtlChange	(0x0B0)			// controller change
#define midiMsgBaseProgChange	(0x0C0)			// program change
#define midiMsgBaseChanPress	(0x0D0)			// channel pressure (aftertouch)
#define midiMsgBasePitchBend	(0x0E0)			// pitch bend change


// SMF event status values
#define midiSmfEvtStatusMeta		(0xFF)		// SMF Meta event
#define midiSmfEvtStatusSysExF0	(0xF0)		// SMF System Exclusive event beginning with 0xF0
#define midiSmfEvtStatusSysExF7	(0xF7)		// SMF System Exclusive event beginning with 0xF7


// SMF Meta event type values of interest
#define midiSmfMetaEvtTypeEOT		(0x2F)		// End Of Track (requred at the end of all tracks)
#define midiSmfMetaEvtTypeTempo	(0x51)		// Set Tempo


// MIDI and SMF masks and special bits
#define midiStatusBit			(0x80)			// this bit is set in event/message status bytes
#define midiChanNumMask			(0x0F)			// channel number mask for channel message status
#define midiChanMsgMask			(0xF0)			// channel message id mask for channel message status
#define midiSmfSMPTEDivBit		(0x8000)			// this bit is set in SMPTE Division values
#define midiSmfSMPTEDivTicksMask	(0x00FF)		// ticks per second value mask SMPTE Division values


// MIDI and SMF value bounds
#define midiMinChan				(0)				// minimum MIDI channel number
#define midiMaxChan				(15)				// maximum MIDI channel number

#define midiMinKey				(0)				// mininum note key #
#define midiMaxKey				(127)				// maximum note key #

#define midiMinVel				(0)				// minimum key velocity
#define midiMaxVel				(127)				// maximum key velocity


#define midiSmfMinHdrChunkDataSize	(6)		// minimum SMF header chunk data size
#define midiSmfMinTrkChunkDataSize	(4)		// minimum SMF track chunk data size (minimum
															// delta-time + "end of track" event)


// MIDI value defaults
#define midiDefTempo				(500000L)		// default tempo in microseconds per quarter note
#define midiDefVel				(64)				// default key velocity



// Lengths (in # of bytes) of SMF fixed-length integers
#define midiSmfHdrFmtBytes			(2)			// size of Format field in the SMF header chunk
#define midiSmfHdrTrkBytes			(2)			// size of "# of Tracks" field in the SMF header chunk
#define midiSmfHdrDivBytes			(2)			// size of "Division" field in the SMF header chunk
#define midiSmfChunkTypeBytes		(4)
#define midiSmfChunkLengthBytes	(4)
#define midiSmfTempoBytes			(3)


typedef struct MidiSmfHdrInfoType {
	Word		wFmt;							// one of midiSmfFmt... (default: midiSmfFmtUnknown)
	Word		wNumTracks;					// number of tracks in the MIDI file (default: 0)
	Word		wDivRaw;						// raw Standard MIDI File division value
	Boolean	bUsingSMPTE;				// true if SMPTE is being used (default: false)
	Word		wTicksPerQN;				// # of ticks per quarter note for metrical time (default: 0)
	DWord		dwTicksPerSec;				// # of ticks per second for SMPTE time code time (default: 0)
	} MidiSmfHdrInfoType;
	
	
typedef struct MidiStateType {
	MidiSmfHdrInfoType	hdr;			// digested SMF header info
	
	BytePtr	streamP;						// pointer to SMF stream
	
	// Current SMF chunk info
	BytePtr	chunkEndP;					// pointer to end of current SMF chunk (NULL when unknown)
	DWord		dwChunkType;				// current SMF chunk type
	DWord		dwChunkSize;				// current SMF chunk size
	
	// Event status info
	Byte		bMsgStatus;					// current channel message running status value (0 = none)
	DWord		dwTempo;						// metrical time tempo in microseconds per quarter note
												// (default: 500,000)
	
	// Honored channel range
	Byte		bFirstChan;					// first supported logical MIDI channel in the range 0-15
												// (default 0)
	Byte		bLastChan;					// last supported logical MIDI channel in the range 0-15
												// (default 15)
												
	} MidiStateType;

	
	
typedef enum MidiSmfEvtClassEnum {
	eMidiSmfEvtClassUnknown = 0,
	eMidiSmfEvtClassChannel,
	eMidiSmfEvtClassSysEx,
	eMidiSmfEvtClassMeta
	} MidiSmfEvtClassEnum;


// SMF events
typedef enum MidiSmfEvtEnum {
	eMidiSmfEvtUnknown		= 0,			// unknown SMF event
	
	// SMF Channel events - these values must match
	// the base status values of MIDI channel messages
	eMidiSmfEvtNoteOff		= 0x080,		// note off
	eMidiSmfEvtNoteOn			= 0x090,		// note on
	eMidiSmfEvtPolyPress		= 0x0A0,		// poliphonic key pressure (aftertouch)
	eMidiSmfEvtCtlChange		= 0x0B0,		// controller change
	eMidiSmfEvtProgChange	= 0x0C0,		// program change
	eMidiSmfEvtChanPress		= 0x0D0,		// channel pressure (aftertouch)
	eMidiSmfEvtPitchBend		= 0x0E0,		// pitch bend change
	
	// SMF System Exclusive events
	eMidiSmfEvtSysEx1			= 0x0F0,		// SMF sys exclusive event beginning with 0xF0
	eMidiSmfEvtSysEx2			= 0x0F7,		// SMF sys exclusive event beginning with 0xF7
	
	// SMF Meta events
	eMidiSmfMetaEvtEOT		= 0xFF2F,	// end of track (required at the end of every track)
	eMidiSmfMetaEvtTempo		= 0xFF51,	// set tempo
	eMidiSmfMetaEvtOther		= 0xFF80		// other SMF meta events we're not presently interested in
	
	} MidiSmfEvtEnum;
	
	
typedef struct MidiEventType {
	MidiSmfEvtEnum			id;			// SMF event id
	MidiSmfEvtClassEnum	evtClass;	// SMF event class
	
	DWord		dwDeltaTicks;				// number of PilotOS ticks before the event
	Byte		bChan;						// channel number for channel events (0-15)
	
	// union of event data structures:
	union {
	
		// For the NoteOn/NoteOff events:
		struct {
			Byte		bKey;						// MIDI note key # (0-127)
			Byte		bVel;						// MIDI key velocity/amplitude (0-127)
			} note;
		
		// For the Tempo event:
		struct {
			DWord		dwTempo;					// tempo in microseconds per quarter note
			} setTempo;
	
		} evtData;
	
	} MidiEventType;
	
	




#endif // __MIDI_H__