summaryrefslogtreecommitdiffstats
path: root/arm-wt-22k/lib_src/eas_midi.c
diff options
context:
space:
mode:
Diffstat (limited to 'arm-wt-22k/lib_src/eas_midi.c')
-rw-r--r--arm-wt-22k/lib_src/eas_midi.c569
1 files changed, 0 insertions, 569 deletions
diff --git a/arm-wt-22k/lib_src/eas_midi.c b/arm-wt-22k/lib_src/eas_midi.c
deleted file mode 100644
index 0c77aea..0000000
--- a/arm-wt-22k/lib_src/eas_midi.c
+++ /dev/null
@@ -1,569 +0,0 @@
-/*----------------------------------------------------------------------------
- *
- * File:
- * eas_midi.c
- *
- * Contents and purpose:
- * This file implements the MIDI stream parser. It is called by eas_smf.c to parse MIDI messages
- * that are streamed out of the file. It can also parse live MIDI streams.
- *
- * Copyright Sonic Network Inc. 2005
-
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *----------------------------------------------------------------------------
- * Revision Control:
- * $Revision: 794 $
- * $Date: 2007-08-01 00:08:48 -0700 (Wed, 01 Aug 2007) $
- *----------------------------------------------------------------------------
-*/
-
-#include "eas_data.h"
-#include "eas_report.h"
-#include "eas_miditypes.h"
-#include "eas_midi.h"
-#include "eas_vm_protos.h"
-#include "eas_parser.h"
-
-#ifdef JET_INTERFACE
-#include "jet_data.h"
-#endif
-
-
-/* state enumerations for ProcessSysExMessage */
-typedef enum
-{
- eSysEx,
- eSysExUnivNonRealTime,
- eSysExUnivNrtTargetID,
- eSysExGMControl,
- eSysExUnivRealTime,
- eSysExUnivRtTargetID,
- eSysExDeviceControl,
- eSysExMasterVolume,
- eSysExMasterVolLSB,
- eSysExSPMIDI,
- eSysExSPMIDIchan,
- eSysExSPMIDIMIP,
- eSysExMfgID1,
- eSysExMfgID2,
- eSysExMfgID3,
- eSysExEnhancer,
- eSysExEnhancerSubID,
- eSysExEnhancerFeedback1,
- eSysExEnhancerFeedback2,
- eSysExEnhancerDrive,
- eSysExEnhancerWet,
- eSysExEOX,
- eSysExIgnore
-} E_SYSEX_STATES;
-
-/* local prototypes */
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode);
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode);
-
-/*----------------------------------------------------------------------------
- * EAS_InitMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Initializes the MIDI stream state for parsing.
- *
- * Inputs:
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-void EAS_InitMIDIStream (S_MIDI_STREAM *pMIDIStream)
-{
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- pMIDIStream->runningStatus = 0;
- pMIDIStream->status = 0;
-}
-
-/*----------------------------------------------------------------------------
- * EAS_ParseMIDIStream()
- *----------------------------------------------------------------------------
- * Purpose:
- * Parses a MIDI input stream character by character. Characters are pushed (rather than pulled)
- * so the interface works equally well for both file and stream I/O.
- *
- * Inputs:
- * c - character from MIDI stream
- *
- * Outputs:
- * returns EAS_RESULT (EAS_SUCCESS is OK)
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-EAS_RESULT EAS_ParseMIDIStream (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for new status byte */
- if (c & 0x80)
- {
- /* save new running status */
- if (c < 0xf8)
- {
- pMIDIStream->runningStatus = c;
- pMIDIStream->byte3 = EAS_FALSE;
-
- /* deal with SysEx */
- if ((c == 0xf7) || (c == 0xf0))
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* inform the file parser that we're in the middle of a message */
- if ((c < 0xf4) || (c > 0xf6))
- pMIDIStream->pending = EAS_TRUE;
- }
-
- /* real-time message - ignore it */
- return EAS_SUCCESS;
- }
-
- /* 3rd byte of a 3-byte message? */
- if (pMIDIStream->byte3)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->byte3 = EAS_FALSE;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for status received */
- if (pMIDIStream->runningStatus)
- {
-
- /* save new status and data byte */
- pMIDIStream->status = pMIDIStream->runningStatus;
-
- /* check for 3-byte messages */
- if (pMIDIStream->status < 0xc0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* check for 2-byte messages */
- if (pMIDIStream->status < 0xe0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_FALSE;
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessMIDIMessage(pEASData, pSynth, pMIDIStream, parserMode);
- }
-
- /* check for more 3-bytes message */
- if (pMIDIStream->status < 0xf0)
- {
- pMIDIStream->d1 = c;
- pMIDIStream->pending = EAS_TRUE;
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
-
- /* SysEx message? */
- if (pMIDIStream->status == 0xF0)
- {
- if (parserMode == eParserModeMetaData)
- return EAS_SUCCESS;
- return ProcessSysExMessage(pEASData, pSynth, pMIDIStream, c, parserMode);
- }
-
- /* remaining messages all clear running status */
- pMIDIStream->runningStatus = 0;
-
- /* F2 is 3-byte message */
- if (pMIDIStream->status == 0xf2)
- {
- pMIDIStream->byte3 = EAS_TRUE;
- return EAS_SUCCESS;
- }
- }
-
- /* no status byte received, provide a warning, but we should be able to recover */
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_WARNING, "Received MIDI data without a valid status byte: %d\n",c); */ }
- pMIDIStream->pending = EAS_FALSE;
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessMIDIMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * This function processes a typical MIDI message. All of the data has been received, just need
- * to take appropriate action.
- *
- * Inputs:
- *
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessMIDIMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_INT parserMode)
-{
- EAS_U8 channel;
-
- channel = pMIDIStream->status & 0x0f;
- switch (pMIDIStream->status & 0xf0)
- {
- case 0x80:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- case 0x90:
- if (pMIDIStream->d2)
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOn: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- pMIDIStream->flags |= MIDI_FLAG_FIRST_NOTE;
- if (parserMode == eParserModePlay)
- VMStartNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- else
- {
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"NoteOff: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMStopNote(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- }
- break;
-
- case 0xa0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PolyPres: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- break;
-
- case 0xb0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Control: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMControlChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
-#ifdef JET_INTERFACE
- if (pMIDIStream->jetData & MIDI_FLAGS_JET_CB)
- {
- JET_Event(pEASData, pMIDIStream->jetData & (JET_EVENT_SEG_MASK | JET_EVENT_TRACK_MASK),
- channel, pMIDIStream->d1, pMIDIStream->d2);
- }
-#endif
- break;
-
- case 0xc0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Program: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode <= eParserModeMute)
- VMProgramChange(pEASData->pVoiceMgr, pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xd0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"ChanPres: %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1); */ }
- if (parserMode <= eParserModeMute)
- VMChannelPressure(pSynth, channel, pMIDIStream->d1);
- break;
-
- case 0xe0:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"PBend: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- if (parserMode <= eParserModeMute)
- VMPitchBend(pSynth, channel, pMIDIStream->d1, pMIDIStream->d2);
- break;
-
- default:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL,"Unknown: %02x %02x %02x\n",
- pMIDIStream->status, pMIDIStream->d1, pMIDIStream->d2); */ }
- }
- return EAS_SUCCESS;
-}
-
-/*----------------------------------------------------------------------------
- * ProcessSysExMessage()
- *----------------------------------------------------------------------------
- * Purpose:
- * Process a SysEx character byte from the MIDI stream. Since we cannot
- * simply wait for the next character to arrive, we are forced to save
- * state after each character. It would be easier to parse at the file
- * level, but then we lose the nice feature of being able to support
- * these messages in a real-time MIDI stream.
- *
- * Inputs:
- * pEASData - pointer to synthesizer instance data
- * c - character to be processed
- * locating - if true, the sequencer is relocating to a new position
- *
- * Outputs:
- *
- *
- * Side Effects:
- *
- * Notes:
- * These are the SysEx messages we can receive:
- *
- * SysEx messages
- * { f0 7e 7f 09 01 f7 } GM 1 On
- * { f0 7e 7f 09 02 f7 } GM 1/2 Off
- * { f0 7e 7f 09 03 f7 } GM 2 On
- * { f0 7f 7f 04 01 lsb msb } Master Volume
- * { f0 7f 7f 0b 01 ch mip [ch mip ...] f7 } SP-MIDI
- * { f0 00 01 3a 04 01 fdbk1 fdbk2 drive wet dry f7 } Enhancer
- *
- *----------------------------------------------------------------------------
-*/
-static EAS_RESULT ProcessSysExMessage (S_EAS_DATA *pEASData, S_SYNTH *pSynth, S_MIDI_STREAM *pMIDIStream, EAS_U8 c, EAS_INT parserMode)
-{
-
- /* check for start byte */
- if (c == 0xf0)
- {
- pMIDIStream->sysExState = eSysEx;
- }
- /* check for end byte */
- else if (c == 0xf7)
- {
- /* if this was a MIP message, update the MIP table */
- if ((pMIDIStream->sysExState == eSysExSPMIDIchan) && (parserMode != eParserModeMetaData))
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
-
- /* process SysEx message */
- else
- {
- switch (pMIDIStream->sysExState)
- {
- case eSysEx:
-
- /* first byte, determine message class */
- switch (c)
- {
- case 0x7e:
- pMIDIStream->sysExState = eSysExUnivNonRealTime;
- break;
- case 0x7f:
- pMIDIStream->sysExState = eSysExUnivRealTime;
- break;
- case 0x00:
- pMIDIStream->sysExState = eSysExMfgID1;
- break;
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- break;
-
- /* process GM message */
- case eSysExUnivNonRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivNrtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivNrtTargetID:
- if (c == 0x09)
- pMIDIStream->sysExState = eSysExGMControl;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExGMControl:
- if ((c == 1) || (c == 3))
- {
- /* GM 1 or GM2 On, reset synth */
- if (parserMode != eParserModeMetaData)
- {
- pMIDIStream->flags |= MIDI_FLAG_GM_ON;
- VMReset(pEASData->pVoiceMgr, pSynth, EAS_FALSE);
- VMInitMIPTable(pSynth);
- }
- pMIDIStream->sysExState = eSysExEOX;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* Process Master Volume and SP-MIDI */
- case eSysExUnivRealTime:
- if (c == 0x7f)
- pMIDIStream->sysExState = eSysExUnivRtTargetID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExUnivRtTargetID:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExDeviceControl;
- else if (c == 0x0b)
- pMIDIStream->sysExState = eSysExSPMIDI;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- /* process master volume */
- case eSysExDeviceControl:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMasterVolume;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMasterVolume:
- /* save LSB */
- pMIDIStream->d1 = c;
- pMIDIStream->sysExState = eSysExMasterVolLSB;
- break;
-
- case eSysExMasterVolLSB:
- if (parserMode != eParserModeMetaData)
- {
- EAS_I32 gain = ((EAS_I32) c << 8) | ((EAS_I32) pMIDIStream->d1 << 1);
- gain = (gain * gain) >> 15;
- VMSetVolume(pSynth, (EAS_U16) gain);
- }
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- /* process SP-MIDI MIP message */
- case eSysExSPMIDI:
- if (c == 0x01)
- {
- /* assume all channels are muted */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->d1 = 0;
- pMIDIStream->sysExState = eSysExSPMIDIchan;
- }
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExSPMIDIchan:
- if (c < NUM_SYNTH_CHANNELS)
- {
- pMIDIStream->d2 = c;
- pMIDIStream->sysExState = eSysExSPMIDIMIP;
- }
- else
- {
- /* bad MIP message - unmute channels */
- if (parserMode != eParserModeMetaData)
- VMInitMIPTable(pSynth);
- pMIDIStream->sysExState = eSysExIgnore;
- }
- break;
-
- case eSysExSPMIDIMIP:
- /* process MIP entry here */
- if (parserMode != eParserModeMetaData)
- VMSetMIPEntry(pEASData->pVoiceMgr, pSynth, pMIDIStream->d2, pMIDIStream->d1, c);
- pMIDIStream->sysExState = eSysExSPMIDIchan;
-
- /* if 16 channels received, update MIP table */
- if (++pMIDIStream->d1 == NUM_SYNTH_CHANNELS)
- {
- if (parserMode != eParserModeMetaData)
- VMUpdateMIPTable(pEASData->pVoiceMgr, pSynth);
- pMIDIStream->sysExState = eSysExEOX;
- }
- break;
-
- /* process Enhancer */
- case eSysExMfgID1:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID2:
- if (c == 0x3a)
- pMIDIStream->sysExState = eSysExMfgID1;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExMfgID3:
- if (c == 0x04)
- pMIDIStream->sysExState = eSysExEnhancer;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancer:
- if (c == 0x01)
- pMIDIStream->sysExState = eSysExEnhancerSubID;
- else
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExEnhancerSubID:
- pMIDIStream->sysExState = eSysExEnhancerFeedback1;
- break;
-
- case eSysExEnhancerFeedback1:
- pMIDIStream->sysExState = eSysExEnhancerFeedback2;
- break;
-
- case eSysExEnhancerFeedback2:
- pMIDIStream->sysExState = eSysExEnhancerDrive;
- break;
-
- case eSysExEnhancerDrive:
- pMIDIStream->sysExState = eSysExEnhancerWet;
- break;
-
- case eSysExEnhancerWet:
- pMIDIStream->sysExState = eSysExEOX;
- break;
-
- case eSysExEOX:
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Expected F7, received %02x\n", c); */ }
- pMIDIStream->sysExState = eSysExIgnore;
- break;
-
- case eSysExIgnore:
- break;
-
- default:
- pMIDIStream->sysExState = eSysExIgnore;
- break;
- }
- }
-
- if (pMIDIStream->sysExState == eSysExIgnore)
- { /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Ignoring SysEx byte %02x\n", c); */ }
- return EAS_SUCCESS;
-} /* end ProcessSysExMessage */
-