/*----------------------------------------------------------------------------
 * 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;
}
Ejemplo n.º 2
0
/*----------------------------------------------------------------------------
 * 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 == '#')