[142] | 1 | /* $Id: midimsg.hpp 561 2011-07-28 09:16:56Z rudi $ */
|
---|
| 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).
|
---|
[561] | 57 | const int IBMSysexSigLen = 4;
|
---|
[142] | 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.
|
---|
[561] | 70 | const int MAX_MidiMsgLen = (IBMSysexSigLen + 4 + 2);
|
---|
[142] | 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 | void clear( void ) { _fmemset((PVOID) this, 0, sizeof(MIDIMSG)); }
|
---|
| 80 |
|
---|
| 81 | // Query current message length.
|
---|
| 82 | int length( void ) { return _length; }
|
---|
| 83 |
|
---|
| 84 | // Concatenate 1 byte to end of message.
|
---|
| 85 | void addByte( MIDIBYTE b );
|
---|
| 86 |
|
---|
| 87 | // Do we have a complete message?
|
---|
| 88 | BOOL isComplete( void );
|
---|
| 89 |
|
---|
| 90 | // Is the message unsupported?
|
---|
| 91 | BOOL isUnsupported( void );
|
---|
| 92 |
|
---|
| 93 | // Does current message match the IBM Sysex signature?
|
---|
| 94 | BOOL isIBMSignature() {
|
---|
| 95 | return( (_length >= IBMSysexSigLen) && (*((ULONG*) _msg) == 0x3A0000F0) );
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | // Delete the IBM signature prefix from the front of an IBM Sysex msg.
|
---|
| 99 | VOID discardSignature( void );
|
---|
| 100 |
|
---|
| 101 | // Return byte in the message buffer. No range checking -- too
|
---|
| 102 | // expensive a performance hit.
|
---|
| 103 | inline const MIDIBYTE operator [] (int index) { return _msg[index]; }
|
---|
| 104 |
|
---|
| 105 | // Flush message to a MIDI hardware object using writeByte() method.
|
---|
| 106 | VOID flush( MIDIAUDIO* pmhw );
|
---|
| 107 |
|
---|
| 108 | private:
|
---|
| 109 | // Private data.
|
---|
| 110 |
|
---|
| 111 | int _length; // Number of bytes that we've accumulated
|
---|
| 112 | // in the current message.
|
---|
| 113 | int _expectedLength; // Expected length of messages based on
|
---|
| 114 | // bytes accumulated; 0 if don't know,
|
---|
| 115 | // <0 if unimplemented MIDI message (some
|
---|
| 116 | // of the IBM sysex messages are not implemented.
|
---|
| 117 | UCHAR _msg[ MAX_MidiMsgLen ]; // Message content.
|
---|
| 118 |
|
---|
| 119 | // Private methods.
|
---|
| 120 |
|
---|
| 121 | // Query expected length of message currently being assembled.
|
---|
| 122 | int _queryExpectedLength( void );
|
---|
| 123 |
|
---|
| 124 | // Query expected length - helper function for IBM sysex messages.
|
---|
| 125 | int _queryExpectedSysexLength( void );
|
---|
| 126 | };
|
---|
| 127 |
|
---|
| 128 | #endif
|
---|