mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-16 09:11:17 +00:00
- Fixed: The softsynths could get stuck on the last notes of nonlooping songs.
SVN r3426 (trunk)
This commit is contained in:
parent
957f67f7cc
commit
f94b38fd7f
2 changed files with 74 additions and 15 deletions
|
@ -432,6 +432,8 @@ protected:
|
||||||
|
|
||||||
void OutputVolume (DWORD volume);
|
void OutputVolume (DWORD volume);
|
||||||
int FillBuffer(int buffer_num, int max_events, DWORD max_time);
|
int FillBuffer(int buffer_num, int max_events, DWORD max_time);
|
||||||
|
int FillStopBuffer(int buffer_num);
|
||||||
|
DWORD *WriteStopNotes(DWORD *events);
|
||||||
int ServiceEvent();
|
int ServiceEvent();
|
||||||
int VolumeControllerChange(int channel, int volume);
|
int VolumeControllerChange(int channel, int volume);
|
||||||
int ClampLoopCount(int loopcount);
|
int ClampLoopCount(int loopcount);
|
||||||
|
|
|
@ -485,7 +485,7 @@ void MIDIStreamer::Resume()
|
||||||
|
|
||||||
void MIDIStreamer::Stop()
|
void MIDIStreamer::Stop()
|
||||||
{
|
{
|
||||||
EndQueued = 2;
|
EndQueued = 4;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (PlayerThread != NULL)
|
if (PlayerThread != NULL)
|
||||||
{
|
{
|
||||||
|
@ -653,7 +653,7 @@ void MIDIStreamer::Callback(unsigned int uMsg, void *userdata, DWORD dwParam1, D
|
||||||
{
|
{
|
||||||
MIDIStreamer *self = (MIDIStreamer *)userdata;
|
MIDIStreamer *self = (MIDIStreamer *)userdata;
|
||||||
|
|
||||||
if (self->EndQueued > 1)
|
if (self->EndQueued >= 4)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -813,7 +813,7 @@ int MIDIStreamer::ServiceEvent()
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (EndQueued == 1)
|
if (EndQueued == 2)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -822,7 +822,18 @@ int MIDIStreamer::ServiceEvent()
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
fill:
|
fill:
|
||||||
res = FillBuffer(BufferNum, MAX_EVENTS, MAX_TIME);
|
if (EndQueued == 1)
|
||||||
|
{
|
||||||
|
res = FillStopBuffer(BufferNum);
|
||||||
|
if ((res & 3) != SONG_ERROR)
|
||||||
|
{
|
||||||
|
EndQueued = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res = FillBuffer(BufferNum, MAX_EVENTS, MAX_TIME);
|
||||||
|
}
|
||||||
switch (res & 3)
|
switch (res & 3)
|
||||||
{
|
{
|
||||||
case SONG_MORE:
|
case SONG_MORE:
|
||||||
|
@ -925,17 +936,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time)
|
||||||
if (Restarting)
|
if (Restarting)
|
||||||
{
|
{
|
||||||
Restarting = false;
|
Restarting = false;
|
||||||
// Stop all notes in case any were left hanging.
|
events = WriteStopNotes(events); // Stop all notes in case any were left hanging.
|
||||||
for (i = 0; i < 16; ++i)
|
|
||||||
{
|
|
||||||
events[0] = 0; // dwDeltaTime
|
|
||||||
events[1] = 0; // dwStreamID
|
|
||||||
events[2] = MIDI_CTRLCHANGE | i | (123 << 8); // All notes off
|
|
||||||
events[3] = 0;
|
|
||||||
events[4] = 0;
|
|
||||||
events[5] = MIDI_CTRLCHANGE | i | (121 << 8); // Reset controllers
|
|
||||||
events += 6;
|
|
||||||
}
|
|
||||||
DoRestart();
|
DoRestart();
|
||||||
}
|
}
|
||||||
events = MakeEvents(events, max_event_p, max_time);
|
events = MakeEvents(events, max_event_p, max_time);
|
||||||
|
@ -951,6 +952,62 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time)
|
||||||
return SONG_MORE;
|
return SONG_MORE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// MIDIStreamer :: FillStopBuffer
|
||||||
|
//
|
||||||
|
// Fills a MIDI buffer with events to stop all channels.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
int MIDIStreamer::FillStopBuffer(int buffer_num)
|
||||||
|
{
|
||||||
|
DWORD *events = Events[buffer_num], *max_event_p;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
events = WriteStopNotes(events);
|
||||||
|
|
||||||
|
// wait some tics, just so that this buffer takes some time
|
||||||
|
events[0] = 500;
|
||||||
|
events[1] = 0;
|
||||||
|
events[2] = MEVT_NOP << 24;
|
||||||
|
events += 3;
|
||||||
|
|
||||||
|
memset(&Buffer[buffer_num], 0, sizeof(MIDIHDR));
|
||||||
|
Buffer[buffer_num].lpData = (LPSTR)Events[buffer_num];
|
||||||
|
Buffer[buffer_num].dwBufferLength = DWORD((LPSTR)events - Buffer[buffer_num].lpData);
|
||||||
|
Buffer[buffer_num].dwBytesRecorded = Buffer[buffer_num].dwBufferLength;
|
||||||
|
if (0 != (i = MIDI->PrepareHeader(&Buffer[buffer_num])))
|
||||||
|
{
|
||||||
|
return SONG_ERROR | (i << 2);
|
||||||
|
}
|
||||||
|
return SONG_MORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// MIDIStreamer :: WriteStopNotes
|
||||||
|
//
|
||||||
|
// Generates MIDI events to stop all notes and reset controllers on
|
||||||
|
// every channel.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
DWORD *MIDIStreamer::WriteStopNotes(DWORD *events)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
{
|
||||||
|
events[0] = 0; // dwDeltaTime
|
||||||
|
events[1] = 0; // dwStreamID
|
||||||
|
events[2] = MIDI_CTRLCHANGE | i | (123 << 8); // All notes off
|
||||||
|
events[3] = 0;
|
||||||
|
events[4] = 0;
|
||||||
|
events[5] = MIDI_CTRLCHANGE | i | (121 << 8); // Reset controllers
|
||||||
|
events += 6;
|
||||||
|
}
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// MIDIStreamer :: Precache
|
// MIDIStreamer :: Precache
|
||||||
|
|
Loading…
Reference in a new issue