Added detection of channel messages to fix running status.
This commit is contained in:
		
							parent
							
								
									5a55f715da
								
							
						
					
					
						commit
						6f0535be90
					
				|  | @ -109,8 +109,9 @@ public: | |||
|     inline void setInputChannel(Channel inChannel); | ||||
|      | ||||
| public: | ||||
|     static inline MidiType getTypeFromStatusByte(const byte inStatus); | ||||
| 	 | ||||
|     static inline MidiType getTypeFromStatusByte(byte inStatus); | ||||
| 	static inline bool isChannelMessage(MidiType inType); | ||||
|      | ||||
| private: | ||||
|     bool inputFilter(Channel inChannel); | ||||
|     bool parse(Channel inChannel); | ||||
|  |  | |||
|  | @ -514,50 +514,39 @@ bool MidiInterface<SerialPort>::parse(Channel inChannel) | |||
|         mPendingMessage[0] = extracted; | ||||
|          | ||||
|         // Check for running status first
 | ||||
|         switch (getTypeFromStatusByte(mRunningStatus_RX)) | ||||
|         if (isChannelMessage(getTypeFromStatusByte(mRunningStatus_RX))) | ||||
|         { | ||||
|                 // Only these types allow Running Status:
 | ||||
|             case NoteOff: | ||||
|             case NoteOn: | ||||
|             case AfterTouchPoly: | ||||
|             case ControlChange: | ||||
|             case ProgramChange: | ||||
|             case AfterTouchChannel: | ||||
|             case PitchBend: | ||||
|             // Only these types allow Running Status
 | ||||
|                  | ||||
|                 // If the status byte is not received, prepend it 
 | ||||
|                 // to the pending message
 | ||||
|                 if (extracted < 0x80) | ||||
|                 { | ||||
|                     mPendingMessage[0] = mRunningStatus_RX; | ||||
|                     mPendingMessage[1] = extracted; | ||||
|                     mPendingMessageIndex = 1; | ||||
|                 } | ||||
|                 // Else: well, we received another status byte,
 | ||||
|                 // so the running status does not apply here.
 | ||||
|                 // It will be updated upon completion of this message.
 | ||||
|             // If the status byte is not received, prepend it 
 | ||||
|             // to the pending message
 | ||||
|             if (extracted < 0x80) | ||||
|             { | ||||
|                 mPendingMessage[0] = mRunningStatus_RX; | ||||
|                 mPendingMessage[1] = extracted; | ||||
|                 mPendingMessageIndex = 1; | ||||
|             } | ||||
|             // Else: well, we received another status byte,
 | ||||
|             // so the running status does not apply here.
 | ||||
|             // It will be updated upon completion of this message.
 | ||||
|              | ||||
|             if (mPendingMessageIndex >= (mPendingMessageExpectedLenght-1)) | ||||
|             { | ||||
|                 mMessage.type = getTypeFromStatusByte(mPendingMessage[0]); | ||||
|                 mMessage.channel = (mPendingMessage[0] & 0x0F)+1; | ||||
|                 mMessage.data1 = mPendingMessage[1]; | ||||
|                  | ||||
|                 if (mPendingMessageIndex >= (mPendingMessageExpectedLenght-1)) | ||||
|                 { | ||||
|                     mMessage.type = getTypeFromStatusByte(mPendingMessage[0]); | ||||
|                     mMessage.channel = (mPendingMessage[0] & 0x0F)+1; | ||||
|                     mMessage.data1 = mPendingMessage[1]; | ||||
|                      | ||||
|                     // Save data2 only if applicable
 | ||||
|                     if (mPendingMessageExpectedLenght == 3) | ||||
|                         mMessage.data2 = mPendingMessage[2]; | ||||
|                     else  | ||||
|                         mMessage.data2 = 0; | ||||
|                      | ||||
|                     mPendingMessageIndex = 0; | ||||
|                     mPendingMessageExpectedLenght = 0; | ||||
|                     mMessage.valid = true; | ||||
|                     return true; | ||||
|                 } | ||||
|                 break; | ||||
|             default: | ||||
|                 // No running status
 | ||||
|                 break; | ||||
|                 // Save data2 only if applicable
 | ||||
|                 if (mPendingMessageExpectedLenght == 3) | ||||
|                     mMessage.data2 = mPendingMessage[2]; | ||||
|                 else  | ||||
|                     mMessage.data2 = 0; | ||||
|                  | ||||
|                 mPendingMessageIndex = 0; | ||||
|                 mPendingMessageExpectedLenght = 0; | ||||
|                 mMessage.valid = true; | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         switch (getTypeFromStatusByte(mPendingMessage[0])) | ||||
|  | @ -717,8 +706,11 @@ bool MidiInterface<SerialPort>::parse(Channel inChannel) | |||
|             } | ||||
|              | ||||
|             mMessage.type = getTypeFromStatusByte(mPendingMessage[0]); | ||||
|             // Don't check if it is a Channel Message
 | ||||
|             mMessage.channel = (mPendingMessage[0] & 0x0F)+1; | ||||
|              | ||||
|             if (isChannelMessage(mMessage.type)) | ||||
|                 mMessage.channel = (mPendingMessage[0] & 0x0F)+1; | ||||
|             else | ||||
|                 mMessage.channel = 0; | ||||
|              | ||||
|             mMessage.data1 = mPendingMessage[1]; | ||||
|              | ||||
|  | @ -908,7 +900,7 @@ void MidiInterface<SerialPort>::setInputChannel(Channel inChannel) | |||
|  made public so you can handle MidiTypes more easily. | ||||
|  */ | ||||
| template<class SerialPort> | ||||
| MidiType MidiInterface<SerialPort>::getTypeFromStatusByte(const byte inStatus)  | ||||
| MidiType MidiInterface<SerialPort>::getTypeFromStatusByte(byte inStatus)  | ||||
| { | ||||
|     if ((inStatus  < 0x80) || | ||||
|         (inStatus == 0xF4) || | ||||
|  | @ -919,6 +911,18 @@ MidiType MidiInterface<SerialPort>::getTypeFromStatusByte(const byte inStatus) | |||
|     else return (MidiType)inStatus; | ||||
| } | ||||
| 
 | ||||
| template<class SerialPort> | ||||
| bool MidiInterface<SerialPort>::isChannelMessage(MidiType inType) | ||||
| { | ||||
|     return (inType == NoteOff           || | ||||
|             inType == NoteOn            || | ||||
|             inType == ControlChange     || | ||||
|             inType == AfterTouchPoly    || | ||||
|             inType == AfterTouchChannel || | ||||
|             inType == PitchBend         || | ||||
|             inType == ProgramChange); | ||||
| } | ||||
| 
 | ||||
| // -----------------------------------------------------------------------------
 | ||||
| 
 | ||||
| #if MIDI_USE_CALLBACKS | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Francois Best
						Francois Best