# HG changeset patch # User Masonwheeler # Date 1312694338 25200 # Node ID aff3d57c5a8afea8223096528253f489a95f7a26 # Parent 828e3ea85e8f0dab00865a89e9c298a836b20f26 Added proper support for MIDI looping and lead-in silence culling. diff -r 828e3ea85e8f -r aff3d57c5a8a native_midi/native_midi_win32.c --- a/native_midi/native_midi_win32.c Fri Apr 29 20:30:25 2011 -0700 +++ b/native_midi/native_midi_win32.c Sat Aug 06 22:18:58 2011 -0700 @@ -42,6 +42,7 @@ Uint16 ppqn; int Size; int NewPos; + int LoopPos; }; static UINT MidiDevice=MIDI_MAPPER; @@ -58,7 +59,15 @@ // proff 12/8/98: Added for savety midiOutUnprepareHeader((HMIDIOUT)hMidiStream,&song->MidiStreamHdr,sizeof(MIDIHDR)); if (song->NewPos>=song->Size) - return 0; + { + int loopPos = song->LoopPos; + if ((!loopPos) || (loopPos >= song->NewPos)) + { + song->MusicPlaying=0; + return 0; + } + song->NewPos = (3*sizeof(DWORD)) * song->LoopPos; + } BlockSize=(song->Size-song->NewPos); if (BlockSize<=0) return 0; @@ -83,6 +92,9 @@ int eventcount; MIDIEvent *event; MIDIEVENT *newevent; + int stripout = 0; + int lastTime = 0; + int playing = 0; eventcount=0; event=evntlist; @@ -104,17 +116,27 @@ int status = (event->status&0xF0)>>4; switch (status) { + case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_NOTE_OFF: - case MIDI_STATUS_NOTE_ON: case MIDI_STATUS_AFTERTOUCH: case MIDI_STATUS_CONTROLLER: case MIDI_STATUS_PROG_CHANGE: case MIDI_STATUS_PRESSURE: case MIDI_STATUS_PITCH_WHEEL: - newevent->dwDeltaTime=event->time; - newevent->dwEvent=(event->status|0x80)|(event->data[0]<<8)|(event->data[1]<<16)|(MEVT_SHORTMSG<<24); - newevent=(MIDIEVENT*)((char*)newevent+(3*sizeof(DWORD))); - eventcount++; + if (!playing){ + int diff = event->time - lastTime; + if (diff > 1) + stripout += (diff - 1); + lastTime = event->time; + } + if (status == MIDI_STATUS_NOTE_ON) + playing = 1; + if ((status == 11) && (event->data[0] == 111)) + song->LoopPos = eventcount; + newevent->dwDeltaTime=event->time - stripout; + newevent->dwEvent=(event->status|0x80)|(event->data[0]<<8)|(event->data[1]<<16)|(MEVT_SHORTMSG<<24); + newevent=(MIDIEVENT*)((char*)newevent+(3*sizeof(DWORD))); + eventcount++; break; case MIDI_STATUS_SYSEX: @@ -148,7 +170,7 @@ temptime=newevent->dwDeltaTime; newevent->dwDeltaTime-=time; time=temptime; - if ((song->NewPos+12)>=song->Size) + if (((song->NewPos+12)>=song->Size) && (!song->LoopPos)) newevent->dwEvent |= MEVT_F_CALLBACK; newevent=(MIDIEVENT*)((char*)newevent+(3*sizeof(DWORD))); song->NewPos+=12; @@ -296,7 +318,9 @@ int native_midi_active() { - return currentsong->MusicPlaying; + if (currentsong) + return currentsong->MusicPlaying; + else return 0; } void native_midi_setvolume(int volume)