Esempio n. 1
0
// --------------
// BuildNewTracks
//
// This is where the actual work gets done.
//
// Until all tracks are done,
//  Scan the tracks to find the next due event
//  Figure out where the event belongs in the new mapping
//  Put it there
// Add end of track metas to all new tracks that now have any data
//
// Return TRUE on success
// Prints its own error message if something goes wrong
// --------------
static BOOL BuildNewTracks(VOID)
{
	LPINTRACKSTATE  pInTrack;
	LPINTRACKSTATE  pInTrackFound;
	UINT            idx;
	DWORD           tkNext;
	TEMPEVENT       me;

	for (;;)
	{
		// Find nearest event due
		//
		pInTrackFound = NULL;
		tkNext = 0xFFFFFFFFL;

		for (idx = 0, pInTrack = ifs.pTracks; idx < ifs.nTracks; ++idx, ++pInTrack) {
			if ((!(pInTrack->fdwTrack & ITS_F_ENDOFTRK)) && (pInTrack->tkNextEventDue < tkNext))
			{
				tkNext = pInTrack->tkNextEventDue;
				pInTrackFound = pInTrack;
			}
		}

		// None found? We must be done
		//
		if (!pInTrackFound)
			break;

		// Ok, get the event header from that track
		//
		if (!GetTrackEvent(pInTrackFound, &me))
		{
			I_OutputMsg("MIDI file is corrupt!\n");
			return FALSE;
		}

		// Don't add end of track event 'til we're done
		//
		if (me.abEvent[0] == MIDI_META && me.abEvent[1] == MIDI_META_EOT)
			continue;

		if (!AddEventToStream(&me))
		{
			I_OutputMsg("Out of memory building tracks.\n");
			return FALSE;
		}
	}

	return TRUE;
}
Esempio n. 2
0
int ConvertToBuffer( DWORD dwFlags, LPCONVERTINFO lpciInfo )
    {
    static INTRACKSTATE *ptsTrack, *ptsFound;
    static DWORD    dwStatus;
    static DWORD    tkNext;
    static TEMPEVENT    teTemp;

    int     nChkErr;
    DWORD   idx;

    lpciInfo->dwBytesRecorded = 0;

    if( dwFlags & CONVERTF_RESET )
    {
    dwProgressBytes = 0;
    dwStatus = 0;
    memset( &teTemp, 0, sizeof(TEMPEVENT));
    ptsTrack = ptsFound = NULL;
    }
    // If we were already done, then return with a warning...
    if( dwStatus & CONVERTF_STATUS_DONE )
    {
    if( bLooped )
        {
        RewindConverter();
        dwProgressBytes = 0;
        dwStatus = 0;
        }
    else
	 {
        return( CONVERTERR_DONE );
	 }
    }
    // The caller is asking us to continue, but we're already hosed because we
    // previously identified something as corrupt, so complain louder this time.
    else if( dwStatus & CONVERTF_STATUS_STUCK )
        {
    return( CONVERTERR_STUCK );
    }
    else if( dwStatus & CONVERTF_STATUS_GOTEVENT )
        {
    // Turn off this bit flag
    dwStatus ^= CONVERTF_STATUS_GOTEVENT;

    /*
     *  The following code for this case is duplicated from below, and is
     * designed to handle a "straggler" event, should we have one left over
     * from previous processing the last time this function was called.
     */

    // Don't add end of track event 'til we're done
    //
    if( teTemp.byShortData[0] == MIDI_META
                    && teTemp.byShortData[1] == MIDI_META_EOT )
        {
        if( dwMallocBlocks )
        {
        free( teTemp.pLongData );
        dwMallocBlocks--;
        }
        }

    else if(( nChkErr = AddEventToStreamBuffer( &teTemp, lpciInfo ))
                            != CONVERTERR_NOERROR )
        {
        if( nChkErr == CONVERTERR_BUFFERFULL )
        {
        // Do some processing and tell caller that this buffer's full
        dwStatus |= CONVERTF_STATUS_GOTEVENT;
        return( CONVERTERR_NOERROR );
        }
        else if( nChkErr == CONVERTERR_METASKIP )
        {
        // We skip by all meta events that aren't tempo changes...
        }
        else
        {
        DebugPrint( "Unable to add event to stream buffer." );
        if( dwMallocBlocks )
            {
            free( teTemp.pLongData );
            dwMallocBlocks--;
            }
        return( TRUE );
        }
        }
    }

    for( ; ; )
        {
        ptsFound = NULL;
        tkNext = 0xFFFFFFFFL;
        // Find nearest event due
        //
        for( idx = 0, ptsTrack = ifs.pitsTracks; idx < ifs.dwTrackCount;
                                    ++idx, ++ptsTrack )
            {
            if(( !( ptsTrack->fdwTrack & ITS_F_ENDOFTRK ))
            && ( ptsTrack->tkNextEventDue < tkNext ))
                {
                tkNext = ptsTrack->tkNextEventDue;
                ptsFound = ptsTrack;
                }
        }

    // None found?  We must be done, so return to the caller with a smile.
    //
    if( !ptsFound )
        {
        dwStatus |= CONVERTF_STATUS_DONE;
            // Need to set return buffer members properly
        return( CONVERTERR_NOERROR );
        }

    // Ok, get the event header from that track
    //
    if( GetTrackEvent( ptsFound, &teTemp ))
            {
        // Warn future calls that this converter is stuck at a corrupt spot
        // and can't continue
            dwStatus |= CONVERTF_STATUS_STUCK;
            return( CONVERTERR_CORRUPT );
            }

    // Don't add end of track event 'til we're done
    //
    if( teTemp.byShortData[0] == MIDI_META
                    && teTemp.byShortData[1] == MIDI_META_EOT )
        {
        if( dwMallocBlocks )
        {
        free( teTemp.pLongData );
        dwMallocBlocks--;
        }
        continue;
        }

    if(( nChkErr = AddEventToStreamBuffer( &teTemp, lpciInfo ))
                            != CONVERTERR_NOERROR )
        {
        if( nChkErr == CONVERTERR_BUFFERFULL )
        {
        // Do some processing and tell somebody this buffer is full...
        dwStatus |= CONVERTF_STATUS_GOTEVENT;
        return( CONVERTERR_NOERROR );
        }
        else if( nChkErr == CONVERTERR_METASKIP )
        {
        // We skip by all meta events that aren't tempo changes...
        }
        else
        {
        DebugPrint( "Unable to add event to stream buffer." );
        if( dwMallocBlocks )
            {
            free( teTemp.pLongData );
            dwMallocBlocks--;
            }
        return( TRUE );
        }
        }
        }   

    return( CONVERTERR_NOERROR );
    }
Esempio n. 3
0
/* ConvertToBuffer
 *
 * Converts MIDI data from the track buffers setup by a previous call
 * to ConverterInit().  Converts data until an error is encountered
 * or the output buffer has been filled with as much event data as possible,
 * not to exceed maxlen.
 *
 * Success/failure and the number of output bytes actually converted will
 * be returned in the convert_buf structure.
 */
int ConvertToBuffer (unsigned int flags, convert_buf_t *buf)
{
	static track_state_t	*ts, *found;
	static DWORD		status;
	static DWORD		next_time;
	static temp_event_t	tevent;

	int		err;
	DWORD		idx;

	buf->bytes_in = 0;

	if (flags & CONVERTF_RESET)
	{
		status = 0;
		memset(&tevent, 0, sizeof(struct _temp_event_s));
		ts = found = NULL;
	}

	/* If we were already done, then return with a warning */
	if (status & CONVERTF_STATUS_DONE)
	{
		if (!bgmloop)
			return CONVERTERR_DONE;

		RewindConverter();
		status = 0;
	}
	/* The caller is asking us to continue, but we're already hosed because
	 * we previously identified something as corrupt, so complain louder this
	 * time. */
	else if (status & CONVERTF_STATUS_STUCK)
	{
		return CONVERTERR_STUCK;
	}
	else if (status & CONVERTF_STATUS_GOTEVENT)
	{
		/* Turn off this bit flag */
		status ^= CONVERTF_STATUS_GOTEVENT;

		/* The following code for this case is duplicated from below,
		 * and is designed to handle a "straggler" event, should we
		 * have one left over from previous processing the last time
		 * this function was called.
		 */

		/* Don't add end of track event until we are done */
		if (tevent.shortdata[0] == MIDI_META_EVENT &&
		    tevent.shortdata[1] == MIDI_META_EOT)
		{
			if (tevent.longdata)
			{
				Z_Free(tevent.longdata);
				tevent.longdata = NULL;
			}
		}
		else if ((err = AddEventToStreamBuffer(&tevent, buf)) != CONVERTERR_NOERROR)
		{
			if (err == CONVERTERR_BUFFERFULL)
			{
			/* Do some processing and tell caller that this buffer is full */
				status |= CONVERTF_STATUS_GOTEVENT;
				return CONVERTERR_NOERROR;
			}
			else if (err == CONVERTERR_METASKIP)
			{
			/* We skip by all meta events that aren't tempo changes */
			}
			else
			{
				DEBUG_Printf("MIDI: %s\n", err_add_event);
				if (tevent.longdata)
				{
					Z_Free(tevent.longdata);
					tevent.longdata = NULL;
				}
				return err;
			}
		}
	}

	for ( ; ; )
	{
		found = NULL;
		next_time = ~(DWORD)0;	/* 0xFFFFFFFFL */

		/* Find nearest event due */
		for (idx = 0, ts = mfs.tracks; idx < mfs.numtracks; ++idx, ++ts)
		{
			if (!(ts->status & ITS_F_ENDOFTRK) &&
				ts->next_event_time < next_time)
			{
				next_time = ts->next_event_time;
				found = ts;
			}
		}

		/* None found? We must be done, so return to the caller with a smile. */
		if (!found)
		{
			status |= CONVERTF_STATUS_DONE;
			return CONVERTERR_NOERROR;
		}

		/* Ok, get the event header from that track */
		if (GetTrackEvent(found, &tevent))
		{
			/* Warn future calls that this converter is stuck
			 * at a corrupt spot and can't continue */
			status |= CONVERTF_STATUS_STUCK;
			return CONVERTERR_CORRUPT;
		}

		/* Don't add end of track event 'til we're done */
		if (tevent.shortdata[0] == MIDI_META_EVENT &&
		    tevent.shortdata[1] == MIDI_META_EOT)
		{
			if (tevent.longdata)
			{
				Z_Free(tevent.longdata);
				tevent.longdata = NULL;
			}
			continue;
		}

		if ((err = AddEventToStreamBuffer(&tevent, buf)) != CONVERTERR_NOERROR)
		{
			if (err == CONVERTERR_BUFFERFULL)
			{
			/* Do some processing and tell caller that this buffer is full */
				status |= CONVERTF_STATUS_GOTEVENT;
				return CONVERTERR_NOERROR;
			}
			else if (err == CONVERTERR_METASKIP)
			{
			/* We skip by all meta events that aren't tempo changes */
			}
			else
			{
				DEBUG_Printf("MIDI: %s\n", err_add_event);
				if (tevent.longdata)
				{
					Z_Free(tevent.longdata);
					tevent.longdata = NULL;
				}
				return err;
			}
		}
	}

	return CONVERTERR_NOERROR;	/* not reached. */
}
Esempio n. 4
0
// -------------------------
// Mid2StreamConvertToBuffer
//
// This function converts MIDI data from the track buffers setup by a previous
// call to Mid2StreamConverterInit().  It will convert data until an error is
// encountered or the output buffer has been filled with as much event data
// as possible, not to exceed dwMaxLength. This function can take a couple
// bit flags, passed through dwFlags. Information about the success/failure
// of this operation and the number of output bytes actually converted will
// be returned in the CONVERTINFO structure pointed at by lpciInfo.
// -------------------------
int Mid2StreamConvertToBuffer(DWORD dwFlags, LPCONVERTINFO lpciInfo)
{
	static LPINTRACKSTATE pInTrack, pInTrackFound;
	static DWORD          dwStatus;
	static DWORD          tkNext;
	static TEMPEVENT      teTemp;

	int     nChkErr;
	DWORD   idx;

	lpciInfo->dwBytesRecorded = 0;

	if (dwFlags & CONVERTF_RESET)
	{
		dwProgressBytes = 0;
		dwStatus = 0;
		ZeroMemory(&teTemp, sizeof (TEMPEVENT));
		pInTrack = pInTrackFound = NULL;
	}

	// If we were already done, then return with a warning...
	if (dwStatus & CONVERTF_STATUS_DONE)
	{
		if (bMidiLooped)
		{
			Mid2StreamRewindConverter();
			dwProgressBytes = 0;
			dwStatus = 0;
		}
		else
			return CONVERTERR_DONE;
	}
	// The caller is asking us to continue, but we're already hosed because we
	// previously identified something as corrupt, so complain louder this time.
	else if (dwStatus & CONVERTF_STATUS_STUCK)
		return CONVERTERR_STUCK;
	else if (dwStatus & CONVERTF_STATUS_GOTEVENT)
	{
		// Turn off this bit flag
		dwStatus ^= CONVERTF_STATUS_GOTEVENT;

		// Don't add end of track event 'til we're done
		//
		if (teTemp.abEvent[0] == MIDI_META &&
			teTemp.abEvent[1] == MIDI_META_EOT)
		{
		}
		else if ((nChkErr = AddEventToStreamBuffer(&teTemp, lpciInfo))
		         != CONVERTERR_NOERROR)
		{
			if (nChkErr == CONVERTERR_BUFFERFULL)
			{
				// Do some processing and tell caller that this buffer's full
				dwStatus |= CONVERTF_STATUS_GOTEVENT;
				return CONVERTERR_NOERROR;
			}
			else if (nChkErr == CONVERTERR_METASKIP)
			{
				// We skip by all meta events that aren't tempo changes...
			}
			else
			{
				I_Error("Unable to add event to stream buffer.");
			}
		}
	}

	for (; ;)
	{
		pInTrackFound = NULL;
		tkNext = 0xFFFFFFFFL;

		// Find nearest event due
		//
		for (idx = 0, pInTrack = ifs.pTracks; idx < ifs.nTracks; ++idx, ++pInTrack)
		{
			if ((!(pInTrack->fdwTrack & ITS_F_ENDOFTRK)) && (pInTrack->tkNextEventDue < tkNext))
			{
				tkNext = pInTrack->tkNextEventDue;
				pInTrackFound = pInTrack;
			}
		}

		// None found?  We must be done, so return to the caller with a smile.
		//
		if (!pInTrackFound)
		{
			dwStatus |= CONVERTF_STATUS_DONE;
			// Need to set return buffer members properly
			return CONVERTERR_NOERROR;
		}

		// Ok, get the event header from that track
		//
		if (!GetTrackEvent(pInTrackFound, &teTemp))
		{
			// Warn future calls that this converter is stuck at a corrupt spot
			// and can't continue
			dwStatus |= CONVERTF_STATUS_STUCK;
			return CONVERTERR_CORRUPT;
		}

		// Don't add end of track event 'til we're done
		//
		if (teTemp.abEvent[0] == MIDI_META &&
		    teTemp.abEvent[1] == MIDI_META_EOT)
			continue;

		if ((nChkErr = AddEventToStreamBuffer(&teTemp, lpciInfo))
			!= CONVERTERR_NOERROR)
		{
			if (nChkErr == CONVERTERR_BUFFERFULL)
			{
				// Do some processing and tell somebody this buffer is full...
				dwStatus |= CONVERTF_STATUS_GOTEVENT;
				return CONVERTERR_NOERROR;
			}
			else if (nChkErr == CONVERTERR_METASKIP)
			{
				// We skip by all meta events that aren't tempo changes...
			}
			else
			{
				I_Error("Unable to add event to stream buffer.");
			}
		}
	}

	//return CONVERTERR_NOERROR;
}