mirror of https://github.com/OpenTTD/OpenTTD.git
Fix: Correctly reset playback between songs in win32_m driver
This commit is contained in:
parent
27b7c5a5fd
commit
a0c78c73e3
|
@ -36,7 +36,7 @@ static struct {
|
|||
std::mutex lock; ///< synchronization for playback status fields
|
||||
|
||||
bool playing; ///< flag indicating that playback is active
|
||||
bool do_start; ///< flag for starting playback of next_file at next opportunity
|
||||
int do_start; ///< flag for starting playback of next_file at next opportunity
|
||||
bool do_stop; ///< flag for stopping playback at next opportunity
|
||||
byte current_volume; ///< current effective volume setting
|
||||
byte new_volume; ///< volume setting to change to
|
||||
|
@ -115,66 +115,77 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW
|
|||
std::unique_lock<std::mutex> mutex_lock(_midi.lock, std::defer_lock);
|
||||
if (!mutex_lock.try_lock()) return;
|
||||
|
||||
{
|
||||
/* check for stop */
|
||||
if (_midi.do_stop) {
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set");
|
||||
midiOutReset(_midi.midi_out);
|
||||
_midi.playing = false;
|
||||
_midi.do_stop = false;
|
||||
/* check for stop */
|
||||
if (_midi.do_stop) {
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set");
|
||||
midiOutReset(_midi.midi_out);
|
||||
_midi.playing = false;
|
||||
_midi.do_stop = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for start/restart/change song */
|
||||
if (_midi.do_start != 0) {
|
||||
/* Have a delay between playback start steps, prevents jumbled-together notes at the start of song */
|
||||
if (timeGetTime() - _midi.playback_start_time < 50) {
|
||||
return;
|
||||
}
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: do_start step %d", _midi.do_start);
|
||||
|
||||
/* check for start/restart/change song */
|
||||
if (_midi.do_start) {
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: do_start is set");
|
||||
if (_midi.playing) {
|
||||
midiOutReset(_midi.midi_out);
|
||||
/* Some songs change the "Pitch bend range" registered
|
||||
* parameter. If this doesn't get reset, everything else
|
||||
* will start sounding wrong. */
|
||||
for (int ch = 0; ch < 16; ch++) {
|
||||
/* Running status, only need status for first message */
|
||||
/* Select RPN 00.00, set value to 02.00, and unselect again */
|
||||
TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_RPN_SELECT_LO, 0x00);
|
||||
TransmitChannelMsg(MIDICT_RPN_SELECT_HI, 0x00);
|
||||
TransmitChannelMsg(MIDICT_DATAENTRY, 0x02);
|
||||
TransmitChannelMsg(MIDICT_DATAENTRY_LO, 0x00);
|
||||
TransmitChannelMsg(MIDICT_RPN_SELECT_LO, 0x7F);
|
||||
TransmitChannelMsg(MIDICT_RPN_SELECT_HI, 0x7F);
|
||||
}
|
||||
}
|
||||
if (_midi.do_start == 1) {
|
||||
/* Send "all notes off" */
|
||||
midiOutReset(_midi.midi_out);
|
||||
_midi.playback_start_time = timeGetTime();
|
||||
_midi.do_start = 2;
|
||||
|
||||
return;
|
||||
} else if (_midi.do_start == 2) {
|
||||
/* Reset the device to General MIDI defaults */
|
||||
TransmitStandardSysex(MidiSysexMessage::ResetGM);
|
||||
_midi.playback_start_time = timeGetTime();
|
||||
_midi.do_start = 3;
|
||||
|
||||
return;
|
||||
} else if (_midi.do_start == 3) {
|
||||
/* Set up device-specific effects */
|
||||
TransmitStandardSysex(MidiSysexMessage::RolandSetReverb);
|
||||
_midi.playback_start_time = timeGetTime();
|
||||
_midi.do_start = 4;
|
||||
|
||||
return;
|
||||
} else if (_midi.do_start == 4) {
|
||||
/* Load the new file */
|
||||
_midi.current_file.MoveFrom(_midi.next_file);
|
||||
std::swap(_midi.next_segment, _midi.current_segment);
|
||||
_midi.current_segment.start_block = 0;
|
||||
_midi.playback_start_time = timeGetTime();
|
||||
_midi.playing = true;
|
||||
_midi.do_start = false;
|
||||
_midi.do_start = 0;
|
||||
_midi.current_block = 0;
|
||||
|
||||
MemSetT<byte>(_midi.channel_volumes, 127, lengthof(_midi.channel_volumes));
|
||||
} else if (!_midi.playing) {
|
||||
/* not playing, stop the timer */
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer");
|
||||
timeKillEvent(uTimerID);
|
||||
_midi.timer_id = 0;
|
||||
return;
|
||||
}
|
||||
} else if (!_midi.playing) {
|
||||
/* not playing, stop the timer */
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer");
|
||||
timeKillEvent(uTimerID);
|
||||
_midi.timer_id = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for volume change */
|
||||
static int volume_throttle = 0;
|
||||
if (_midi.current_volume != _midi.new_volume) {
|
||||
if (volume_throttle == 0) {
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: volume change");
|
||||
_midi.current_volume = _midi.new_volume;
|
||||
volume_throttle = 20 / _midi.time_period;
|
||||
for (int ch = 0; ch < 16; ch++) {
|
||||
int vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume);
|
||||
TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol);
|
||||
}
|
||||
} else {
|
||||
volume_throttle--;
|
||||
/* check for volume change */
|
||||
static int volume_throttle = 0;
|
||||
if (_midi.current_volume != _midi.new_volume) {
|
||||
if (volume_throttle == 0) {
|
||||
DEBUG(driver, 2, "Win32-MIDI: timer: volume change");
|
||||
_midi.current_volume = _midi.new_volume;
|
||||
volume_throttle = 20 / _midi.time_period;
|
||||
for (int ch = 0; ch < 16; ch++) {
|
||||
byte vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume);
|
||||
TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol);
|
||||
}
|
||||
} else {
|
||||
volume_throttle--;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,7 +337,7 @@ void MusicDriver_Win32::PlaySong(const MusicSongInfo &song)
|
|||
|
||||
DEBUG(driver, 2, "Win32-MIDI: PlaySong: setting flag");
|
||||
_midi.do_stop = _midi.playing;
|
||||
_midi.do_start = true;
|
||||
_midi.do_start = 1;
|
||||
|
||||
if (_midi.timer_id == 0) {
|
||||
DEBUG(driver, 2, "Win32-MIDI: PlaySong: starting timer");
|
||||
|
@ -344,7 +355,7 @@ void MusicDriver_Win32::StopSong()
|
|||
|
||||
bool MusicDriver_Win32::IsSongPlaying()
|
||||
{
|
||||
return _midi.playing || _midi.do_start;
|
||||
return _midi.playing || (_midi.do_start != 0);
|
||||
}
|
||||
|
||||
void MusicDriver_Win32::SetVolume(byte vol)
|
||||
|
@ -375,12 +386,6 @@ const char *MusicDriver_Win32::Start(const char * const *parm)
|
|||
|
||||
midiOutReset(_midi.midi_out);
|
||||
|
||||
/* Standard "Enable General MIDI" message */
|
||||
TransmitStandardSysex(MidiSysexMessage::ResetGM);
|
||||
|
||||
/* Roland-specific reverb room control, used by the original game */
|
||||
TransmitStandardSysex(MidiSysexMessage::RolandSetReverb);
|
||||
|
||||
/* prepare multimedia timer */
|
||||
TIMECAPS timecaps;
|
||||
if (timeGetDevCaps(&timecaps, sizeof(timecaps)) == MMSYSERR_NOERROR) {
|
||||
|
|
Loading…
Reference in New Issue