156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * File:
456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * eas_midi.c
556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Contents and purpose:
756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * that are streamed out of the file. It can also parse live MIDI streams.
956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
1056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Copyright Sonic Network Inc. 2005
117df30109963092559d3760c0661a020f9daf1030The Android Open Source Project
127df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
137df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * you may not use this file except in compliance with the License.
147df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * You may obtain a copy of the License at
157df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
167df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
177df30109963092559d3760c0661a020f9daf1030The Android Open Source Project *
187df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
197df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
207df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
217df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * See the License for the specific language governing permissions and
227df30109963092559d3760c0661a020f9daf1030The Android Open Source Project * limitations under the License.
2356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
2456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Revision Control:
2656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Revision: 794 $
2756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *   $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
2856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
2956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
3056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_data.h"
3256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_report.h"
3356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_miditypes.h"
3456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_midi.h"
3556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_vm_protos.h"
3656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "eas_parser.h"
3756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
3856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef JET_INTERFACE
3956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#include "jet_data.h"
4056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
4156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
4356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/* state enumerations for ProcessSysExMessage */
4456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparkstypedef enum
4556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
4656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysEx,
4756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExUnivNonRealTime,
4856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExUnivNrtTargetID,
4956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExGMControl,
5056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExUnivRealTime,
5156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExUnivRtTargetID,
5256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExDeviceControl,
5356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExMasterVolume,
5456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExMasterVolLSB,
5556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExSPMIDI,
5656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExSPMIDIchan,
5756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExSPMIDIMIP,
5856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExMfgID1,
5956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExMfgID2,
6056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExMfgID3,
6156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEnhancer,
6256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEnhancerSubID,
6356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEnhancerFeedback1,
6456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEnhancerFeedback2,
6556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEnhancerDrive,
6656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEnhancerWet,
6756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExEOX,
6856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    eSysExIgnore
6956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} E_SYSEX_STATES;
7056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
7156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/* local prototypes */
7256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
7356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
7456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
7556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
7656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * EAS_InitMIDIStream()
7756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
7856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
7956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Initializes the MIDI stream state for parsing.
8056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
8156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
8256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
8356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
8456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * returns EAS_RESULT (EAS_SUCCESS is OK)
8556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
8656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
8756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
8856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
8956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
9056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksvoid EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
9156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
9256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMIDIStream->byte3 = EAS_FALSE;
9356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMIDIStream->pending = EAS_FALSE;
9456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMIDIStream->runningStatus = 0;
9556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMIDIStream->status = 0;
9656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
9756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
9856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
9956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * EAS_ParseMIDIStream()
10056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
10156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
10256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
10356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * so the interface works equally well for both file and stream I/O.
10456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
10656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * c            - character from MIDI stream
10756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
10856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
10956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * returns EAS_RESULT (EAS_SUCCESS is OK)
11056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
11156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
11256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
11356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
11456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
11556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave SparksEAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
11656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
11756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
11856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* check for new status byte */
11956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (c & 0x80)
12056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
12156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* save new running status */
12256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (c < 0xf8)
12356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
12456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->runningStatus = c;
12556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->byte3 = EAS_FALSE;
12656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
12756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* deal with SysEx */
12856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if ((c == 0xf7) || (c == 0xf0))
12956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
13056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (parserMode == eParserModeMetaData)
13156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    return EAS_SUCCESS;
13256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
13356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
13456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
13556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* inform the file parser that we're in the middle of a message */
13656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if ((c < 0xf4) || (c > 0xf6))
13756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->pending = EAS_TRUE;
13856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
13956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* real-time message - ignore it */
14156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return EAS_SUCCESS;
14256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
14356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
14456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* 3rd byte of a 3-byte message? */
14556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pMIDIStream->byte3)
14656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
14756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->d2 = c;
14856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->byte3 = EAS_FALSE;
14956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->pending = EAS_FALSE;
15056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (parserMode == eParserModeMetaData)
15156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return EAS_SUCCESS;
15256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
15356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
15456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
15556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* check for status received */
15656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pMIDIStream->runningStatus)
15756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
15856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
15956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* save new status and data byte */
16056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->status = pMIDIStream->runningStatus;
16156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
16256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* check for 3-byte messages */
16356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->status < 0xc0)
16456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
16556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->d1 = c;
16656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->pending = EAS_TRUE;
16756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->byte3 = EAS_TRUE;
16856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return EAS_SUCCESS;
16956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
17056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
17156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* check for 2-byte messages */
17256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->status < 0xe0)
17356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
17456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->d1 = c;
17556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->pending = EAS_FALSE;
17656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (parserMode == eParserModeMetaData)
17756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                return EAS_SUCCESS;
17856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
17956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
18056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
18156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* check for more 3-bytes message */
18256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->status < 0xf0)
18356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
18456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->d1 = c;
18556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->pending = EAS_TRUE;
18656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->byte3 = EAS_TRUE;
18756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return EAS_SUCCESS;
18856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
18956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
19056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* SysEx message? */
19156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->status == 0xF0)
19256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
19356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (parserMode == eParserModeMetaData)
19456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                return EAS_SUCCESS;
19556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
19656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
19756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
19856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* remaining messages all clear running status */
19956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->runningStatus = 0;
20056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* F2 is 3-byte message */
20256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->status == 0xf2)
20356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
20456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->byte3 = EAS_TRUE;
20556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            return EAS_SUCCESS;
20656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
20756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
20856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
20956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* no status byte received, provide a warning, but we should be able to recover */
21056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
21156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    pMIDIStream->pending = EAS_FALSE;
21256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
21356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
21456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
21556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
21656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * ProcessMIDIMessage()
21756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
21856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
21956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * This function processes a typical MIDI message. All of the data has been received, just need
22056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * to take appropriate action.
22156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
22356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
22656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
22856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
22956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
23056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
23156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
23256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
23356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
23456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    EAS_U8 channel;
23556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
23656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    channel = pMIDIStream->status & 0x0f;
23756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    switch (pMIDIStream->status & 0xf0)
23856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
23956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0x80:
24056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
24156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
24256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (parserMode <= eParserModeMute)
24356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
24456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
24556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
24656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0x90:
24756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->d2)
24856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
24956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
25056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
25156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
25256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (parserMode == eParserModePlay)
25356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
25456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
25556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        else
25656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
25756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
25856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
25956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (parserMode <= eParserModeMute)
26056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
26156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
26256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
26356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0xa0:
26556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
26656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
26756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
26856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
26956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0xb0:
27056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
27156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
27256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (parserMode <= eParserModeMute)
27356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
27456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#ifdef JET_INTERFACE
27556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
27656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
27756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
27856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                channel, pMIDIStream->d1, pMIDIStream->d2);
27956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
28056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks#endif
28156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
28256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
28356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0xc0:
28456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
28556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1); */ }
28656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (parserMode <= eParserModeMute)
28756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
28856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
28956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0xd0:
29156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
29256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1); */ }
29356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (parserMode <= eParserModeMute)
29456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            VMChannelPressure(pSynth, channel, pMIDIStream->d1);
29556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
29656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
29756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    case 0xe0:
29856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
29956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
30056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if (parserMode <= eParserModeMute)
30156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
30256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        break;
30356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
30456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    default:
30556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
30656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
30756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
30856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
30956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks}
31056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
31156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks/*----------------------------------------------------------------------------
31256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * ProcessSysExMessage()
31356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
31456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Purpose:
31556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Process a SysEx character byte from the MIDI stream. Since we cannot
31656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * simply wait for the next character to arrive, we are forced to save
31756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * state after each character. It would be easier to parse at the file
31856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * level, but then we lose the nice feature of being able to support
31956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * these messages in a real-time MIDI stream.
32056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
32156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Inputs:
32256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * pEASData         - pointer to synthesizer instance data
32356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * c                - character to be processed
32456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * locating         - if true, the sequencer is relocating to a new position
32556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
32656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Outputs:
32756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
32856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
32956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Side Effects:
33056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
33156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * Notes:
33256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * These are the SysEx messages we can receive:
33356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
33456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * SysEx messages
33556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * { f0 7e 7f 09 01 f7 } GM 1 On
33656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * { f0 7e 7f 09 02 f7 } GM 1/2 Off
33756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * { f0 7e 7f 09 03 f7 } GM 2 On
33856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * { f0 7f 7f 04 01 lsb msb } Master Volume
33956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
34056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
34156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *
34256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks *----------------------------------------------------------------------------
34356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks*/
34456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparksstatic EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
34556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks{
34656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
34756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* check for start byte */
34856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (c == 0xf0)
34956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
35056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->sysExState = eSysEx;
35156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
35256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* check for end byte */
35356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else if (c == 0xf7)
35456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
35556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* if this was a MIP message, update the MIP table */
35656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
35756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
35856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        pMIDIStream->sysExState = eSysExIgnore;
35956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
36056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    /* process SysEx message */
36256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    else
36356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    {
36456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        switch (pMIDIStream->sysExState)
36556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        {
36656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysEx:
36756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
36856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* first byte, determine message class */
36956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            switch (c)
37056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
37156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            case 0x7e:
37256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExUnivNonRealTime;
37356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                break;
37456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            case 0x7f:
37556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExUnivRealTime;
37656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                break;
37756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            case 0x00:
37856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExMfgID1;
37956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                break;
38056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            default:
38156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
38256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                break;
38356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
38456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
38556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
38656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* process GM message */
38756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExUnivNonRealTime:
38856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x7f)
38956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExUnivNrtTargetID;
39056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
39156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
39256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
39356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
39456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExUnivNrtTargetID:
39556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x09)
39656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExGMControl;
39756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
39856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
39956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
40056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
40156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExGMControl:
40256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if ((c == 1) || (c == 3))
40356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
40456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* GM 1 or GM2 On, reset synth */
40556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (parserMode != eParserModeMetaData)
40656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                {
40756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    pMIDIStream->flags |= MIDI_FLAG_GM_ON;
40856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
40956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    VMInitMIPTable(pSynth);
41056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                }
41156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExEOX;
41256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
41356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
41456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
41556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
41656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
41756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* Process Master Volume and SP-MIDI */
41856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExUnivRealTime:
41956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x7f)
42056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExUnivRtTargetID;
42156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
42256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
42356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
42456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
42556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExUnivRtTargetID:
42656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x04)
42756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExDeviceControl;
42856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else if (c == 0x0b)
42956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExSPMIDI;
43056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
43156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
43256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
43356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
43456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* process master volume */
43556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExDeviceControl:
43656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x01)
43756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExMasterVolume;
43856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
43956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
44056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
44156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
44256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExMasterVolume:
44356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* save LSB */
44456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->d1 = c;
44556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExMasterVolLSB;
44656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
44756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
44856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExMasterVolLSB:
44956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (parserMode != eParserModeMetaData)
45056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
45156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
45256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                gain = (gain * gain) >> 15;
45356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                VMSetVolume(pSynth, (EAS_U16) gain);
45456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
45556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExEOX;
45656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
45756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
45856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* process SP-MIDI MIP message */
45956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExSPMIDI:
46056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x01)
46156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
46256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* assume all channels are muted */
46356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (parserMode != eParserModeMetaData)
46456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    VMInitMIPTable(pSynth);
46556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->d1 = 0;
46656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExSPMIDIchan;
46756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
46856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
46956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
47056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
47156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
47256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExSPMIDIchan:
47356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c < NUM_SYNTH_CHANNELS)
47456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
47556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->d2 = c;
47656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExSPMIDIMIP;
47756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
47856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
47956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
48056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                /* bad MIP message - unmute channels */
48156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (parserMode != eParserModeMetaData)
48256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    VMInitMIPTable(pSynth);
48356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
48456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
48556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
48656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
48756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExSPMIDIMIP:
48856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* process MIP entry here */
48956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (parserMode != eParserModeMetaData)
49056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
49156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExSPMIDIchan;
49256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
49356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            /* if 16 channels received, update MIP table */
49456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
49556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            {
49656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                if (parserMode != eParserModeMetaData)
49756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                    VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
49856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExEOX;
49956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            }
50056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
50156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
50256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        /* process Enhancer */
50356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExMfgID1:
50456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x01)
50556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExMfgID1;
50656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
50756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
50856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
50956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
51056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExMfgID2:
51156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x3a)
51256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExMfgID1;
51356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
51456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
51556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
51656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
51756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExMfgID3:
51856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x04)
51956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExEnhancer;
52056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
52156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
52256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
52356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
52456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEnhancer:
52556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            if (c == 0x01)
52656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExEnhancerSubID;
52756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            else
52856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks                pMIDIStream->sysExState = eSysExIgnore;
52956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
53056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEnhancerSubID:
53256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExEnhancerFeedback1;
53356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
53456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEnhancerFeedback1:
53656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExEnhancerFeedback2;
53756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
53856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
53956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEnhancerFeedback2:
54056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExEnhancerDrive;
54156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
54256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
54356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEnhancerDrive:
54456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExEnhancerWet;
54556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
54656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
54756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEnhancerWet:
54856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExEOX;
54956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
55056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
55156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExEOX:
55256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
55356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExIgnore;
55456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
55556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
55656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        case eSysExIgnore:
55756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
55856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
55956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        default:
56056c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            pMIDIStream->sysExState = eSysExIgnore;
56156c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks            break;
56256c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        }
56356c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    }
56456c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
56556c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    if (pMIDIStream->sysExState == eSysExIgnore)
56656c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks        { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
56756c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks    return EAS_SUCCESS;
56856c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks} /* end ProcessSysExMessage */
56956c99cd2c2c1e6ab038dac5fced5b92ccf11ff6cDave Sparks
570