/*---------------------------------------------------------------------------- * 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; }
/*---------------------------------------------------------------------------- * RTTTL_Event() *---------------------------------------------------------------------------- * Purpose: * Parse the next event in the file * * Inputs: * pEASData - pointer to overall EAS data structure * handle - pointer to file handle * * Outputs: * * * Side Effects: * *---------------------------------------------------------------------------- */ static EAS_RESULT RTTTL_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_INT parserMode) { S_RTTTL_DATA* pData; EAS_RESULT result; EAS_I32 ticks; EAS_I32 temp; EAS_I8 c; EAS_U8 note; EAS_U8 octave; pData = (S_RTTTL_DATA*) pInstData; if (pData->state >= EAS_STATE_OPEN) return EAS_SUCCESS; /* initialize MIDI channel when the track starts playing */ if (pData->time == 0) { /* set program to square lead */ VMProgramChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, RTTTL_PROGRAM); /* set channel volume to max */ VMControlChange(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, 7, 127); } /* check for end of note */ if (pData->note) { /* stop the note */ VMStopNote(pEASData->pVoiceMgr, pData->pSynth, RTTTL_CHANNEL, pData->note, 0); pData->note = 0; /* check for rest between notes */ if (pData->restTicks) { pData->time += pData->restTicks; pData->restTicks = 0; return EAS_SUCCESS; } } /* parse the next event */ octave = pData->octave; note = 0; ticks = pData->duration * pData->tick; for (;;) { /* get next character */ if ((result = RTTTL_GetNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS) { if (result != EAS_EOF) return result; /* end of file, if no notes to process, check for looping */ if (!note) { /* if no loop set state to stopping */ if (pData->repeatCount == 0) { pData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth); return EAS_SUCCESS; } /* decrement loop count */ if (pData->repeatCount != RTTTL_INFINITE_LOOP) pData->repeatCount--; /* if locating, ignore infinite loops */ else if (parserMode != eParserModePlay) { pData->state = EAS_STATE_STOPPING; VMReleaseAllVoices(pEASData->pVoiceMgr, pData->pSynth); return EAS_SUCCESS; } /* loop back to start of notes */ if ((result = EAS_HWFileSeek(pEASData->hwInstData, pData->fileHandle, pData->repeatOffset)) != EAS_SUCCESS) return result; continue; } /* still have a note to process */ else c = ','; } /* bpm */ if (c == 'b') { /* peek at next character */ if ((result = RTTTL_PeekNextChar(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS) return result; /* if a number, must be octave or tempo */ if (IsDigit(c)) { if ((result = RTTTL_GetNumber(pEASData->hwInstData, pData, &temp)) != EAS_SUCCESS) return result; /* check for octave first */ if ((temp >= 4) && (temp <= 7)) { octave = (EAS_U8) temp; } /* check for tempo */ else if ((temp >= 25) && (temp <= 900)) { pData->tick = TICK_CONVERT / (EAS_U32) temp; } /* don't know what it was */ else return EAS_ERROR_FILE_FORMAT; } /* must be a note */ else { note = noteTable[1]; } } /* octave */ else if (c == 'o') { if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &pData->octave)) != EAS_SUCCESS) return result; } /* style */ else if (c == 's') { if ((result = RTTTL_GetStyle(pEASData->hwInstData, pData)) != EAS_SUCCESS) return result; } /* duration or octave */ else if (IsDigit(c)) { RTTTL_PutBackChar(pData, c); /* duration comes before note */ if (!note) { if ((result = RTTTL_GetDuration(pEASData->hwInstData, pData, &c)) != EAS_SUCCESS) return result; ticks = c * pData->tick; } /* octave comes after note */ else { if ((result = RTTTL_GetOctave(pEASData->hwInstData, pData, &octave)) != EAS_SUCCESS) return result; } } /* note or rest */ else if ((c >= 'a') && (c <= 'h')) { note = noteTable[c - 'a']; } else if (c == 'p') { note = RTTTL_REST; } /* dotted note */ else if (c == '.') { /*lint -e{704} shift for performance */ ticks += ticks >> 1; } /* accidental */ else if (c == '#')