| 1 | /* $Id: midimsg.hpp,v 1.1 2000/04/23 14:55:18 ktk Exp $ */
|
|---|
| 2 |
|
|---|
| 3 | /* SCCSID = %W% %E% */
|
|---|
| 4 | /****************************************************************************
|
|---|
| 5 | * *
|
|---|
| 6 | * Copyright (c) IBM Corporation 1994 - 1997. *
|
|---|
| 7 | * *
|
|---|
| 8 | * The following IBM OS/2 source code is provided to you solely for the *
|
|---|
| 9 | * the purpose of assisting you in your development of OS/2 device drivers. *
|
|---|
| 10 | * You may use this code in accordance with the IBM License Agreement *
|
|---|
| 11 | * provided in the IBM Device Driver Source Kit for OS/2. *
|
|---|
| 12 | * *
|
|---|
| 13 | ****************************************************************************/
|
|---|
| 14 | /**@internal %W%
|
|---|
| 15 | * MIDIMSG class definition. Defines a class which is used to assemble
|
|---|
| 16 | * valid MIDI messages, and perform certain predicate queries on the MIDI
|
|---|
| 17 | * message strings (such as "is the message complete?").
|
|---|
| 18 | * @version %I%
|
|---|
| 19 | * @context
|
|---|
| 20 | * Unless otherwise noted, all interfaces are Ring-0, 16-bit, kernel stack.
|
|---|
| 21 | * @notes
|
|---|
| 22 | * See .cpp file for description of the IBM Sysex command.
|
|---|
| 23 | * @history
|
|---|
| 24 | */
|
|---|
| 25 |
|
|---|
| 26 | #ifndef MIDIMSG_INCLUDED
|
|---|
| 27 | #define MIDIMSG_INCLUDED
|
|---|
| 28 |
|
|---|
| 29 | #ifndef OS2_INCLUDED // Doesn't like being included twice.
|
|---|
| 30 | extern "C" { // 16-bit header files are not C++ aware
|
|---|
| 31 | #define INCL_NOPMAPI
|
|---|
| 32 | #include <os2.h>
|
|---|
| 33 | }
|
|---|
| 34 | #endif // end OS2_INCLUDED
|
|---|
| 35 |
|
|---|
| 36 | #include <string.h> // _fmemset()
|
|---|
| 37 | #include "maudio.hpp" // Object definition (MIDIAUDIO).
|
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 | // One byte in a MIDI stream. Must be unsigned.
|
|---|
| 41 | typedef UCHAR MIDIBYTE;
|
|---|
| 42 |
|
|---|
| 43 | // Types of MIDI status bytes.
|
|---|
| 44 | enum MIDIBYTETYPE
|
|---|
| 45 | {
|
|---|
| 46 | MBT_Data, // Not status. Data byte (0x00 - 0x7F)
|
|---|
| 47 | MBT_ChannelStatus, // Channel status byte (0x80 - 0xEF)
|
|---|
| 48 | MBT_Sysex, // System Exclusive (0xF0)
|
|---|
| 49 | MBT_SystemCommon, // System Common (0xF1 - 0xF7)
|
|---|
| 50 | MBT_SystemRT // Real-time (0xF8 - 0xFF)
|
|---|
| 51 | };
|
|---|
| 52 |
|
|---|
| 53 | // Return the MIDIBYTETYPE (enumerated above) of a MIDI byte.
|
|---|
| 54 | extern MIDIBYTETYPE eMidiByteType( MIDIBYTE b );
|
|---|
| 55 |
|
|---|
| 56 | // Byte length of the IBM Sysex Signature (0xF000003A).
|
|---|
| 57 | const IBMSysexSigLen = 4;
|
|---|
| 58 |
|
|---|
| 59 | // Miscellaneous error codes, must be <0.
|
|---|
| 60 | const int MIDIMSG_Err_NotStatus = -1; // Got a data bytes when expected status.
|
|---|
| 61 | const int MIDIMSG_Err_BadSysex = -2; // Unsupported IBM sysex.
|
|---|
| 62 |
|
|---|
| 63 | // 0xF7 EOX
|
|---|
| 64 | const MIDIBYTE MidiByte_EOX = ((MIDIBYTE) 0xF7);
|
|---|
| 65 |
|
|---|
| 66 | // We don't accumulate more than this number of bytes. For vbl length
|
|---|
| 67 | // messages (eg a non-IBM Sysex), we passthru the message byte by byte.
|
|---|
| 68 | // Longest message at time of this writing is 4 byte IBM Sysex signature
|
|---|
| 69 | // plus 4 bytes sysex command and data == 8 bytes. We'll tack on 2 extra.
|
|---|
| 70 | const MAX_MidiMsgLen = (IBMSysexSigLen + 4 + 2);
|
|---|
| 71 |
|
|---|
| 72 | // We use this class to build up MIDI messages as we receive the bytes.
|
|---|
| 73 | class MIDIMSG {
|
|---|
| 74 | public:
|
|---|
| 75 | // Constructor. Clear message.
|
|---|
| 76 | MIDIMSG( void ) { clear(); }
|
|---|
| 77 |
|
|---|
| 78 | // Clear message & set current length, expected length to 0.
|
|---|
| 79 | inline void clear( void ) { memset(this, 0, sizeof(MIDIMSG)); }
|
|---|
| 80 |
|
|---|
| 81 | // Query current message length.
|
|---|
| 82 | inline const int length( void ) { return _length; }
|
|---|
| 83 |
|
|---|
| 84 | // Concatenate 1 byte to end of message.
|
|---|
| 85 | inline void addByte( MIDIBYTE b ) {
|
|---|
| 86 | if (_length < MAX_MidiMsgLen) _msg[_length++] = b;
|
|---|
| 87 | }
|
|---|
| 88 |
|
|---|
| 89 | // Do we have a complete message?
|
|---|
| 90 | BOOL isComplete( void );
|
|---|
| 91 |
|
|---|
| 92 | // Is the message unsupported?
|
|---|
| 93 | inline BOOL isUnsupported( void ) {
|
|---|
| 94 | return _queryExpectedLength() < 0;
|
|---|
| 95 | }
|
|---|
| 96 |
|
|---|
| 97 | // Does current message match the IBM Sysex signature?
|
|---|
| 98 | inline BOOL isIBMSignature() {
|
|---|
| 99 | return( (_length >= IBMSysexSigLen) && (*((ULONG*) _msg) == 0x3A0000F0) );
|
|---|
| 100 | }
|
|---|
| 101 |
|
|---|
| 102 | // Delete the IBM signature prefix from the front of an IBM Sysex msg.
|
|---|
| 103 | VOID discardSignature( void );
|
|---|
| 104 |
|
|---|
| 105 | // Return byte in the message buffer. No range checking -- too
|
|---|
| 106 | // expensive a performance hit.
|
|---|
| 107 | inline const MIDIBYTE operator [] (int index) { return _msg[index]; }
|
|---|
| 108 |
|
|---|
| 109 | // Flush message to a MIDI hardware object using writeByte() method.
|
|---|
| 110 | VOID flush( MIDIAUDIO* pmhw );
|
|---|
| 111 |
|
|---|
| 112 | private:
|
|---|
| 113 | // Private data.
|
|---|
| 114 |
|
|---|
| 115 | int _length; // Number of bytes that we've accumulated
|
|---|
| 116 | // in the current message.
|
|---|
| 117 | int _expectedLength; // Expected length of messages based on
|
|---|
| 118 | // bytes accumulated; 0 if don't know,
|
|---|
| 119 | // <0 if unimplemented MIDI message (some
|
|---|
| 120 | // of the IBM sysex messages are not implemented.
|
|---|
| 121 | UCHAR _msg[ MAX_MidiMsgLen ]; // Message content.
|
|---|
| 122 |
|
|---|
| 123 | // Private methods.
|
|---|
| 124 |
|
|---|
| 125 | // Query expected length of message currently being assembled.
|
|---|
| 126 | int _queryExpectedLength( void );
|
|---|
| 127 |
|
|---|
| 128 | // Query expected length - helper function for IBM sysex messages.
|
|---|
| 129 | int _queryExpectedSysexLength( void );
|
|---|
| 130 | };
|
|---|
| 131 |
|
|---|
| 132 | #endif
|
|---|
| 133 |
|
|---|