mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-13 21:31:53 +00:00
MIDI: Send a reset MIDI device signal on startup.
This is currently done in the engine code. I adapted AGI, AGOS, DRACI, GROOVIE, LURE, MADE, QUEEN, SAGA, SKY, TINSEL and TOUCHE to send a reset device on startup. The sound output still works fine (started up a game from every engine), so this should hopefully not introduce any regressions. As far as I can tell it seems that SCUMM does send a proper device reset, so I did not touch it. KYRA only sends a proper reset for MT-32 currently. I am not sure about SCI though. This fixes bug #3066826 "SIMON: MIDI notes off when using RTL after SCI". svn-id: r52736
This commit is contained in:
parent
bb5db4aa3b
commit
6588398ce6
@ -74,8 +74,12 @@ SoundGenMIDI::SoundGenMIDI(AgiEngine *vm, Audio::Mixer *pMixer) : SoundGen(vm, p
|
||||
DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
|
||||
_driver = MidiDriver::createMidi(dev);
|
||||
|
||||
if (ConfMan.getBool("native_mt32"))
|
||||
if (ConfMan.getBool("native_mt32") || MidiDriver::getMusicType(dev) == MT_MT32) {
|
||||
_nativeMT32 = true;
|
||||
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
||||
} else {
|
||||
_nativeMT32 = false;
|
||||
}
|
||||
|
||||
memset(_channel, 0, sizeof(_channel));
|
||||
memset(_channelVolume, 255, sizeof(_channelVolume));
|
||||
@ -125,10 +129,10 @@ int SoundGenMIDI::open() {
|
||||
|
||||
_driver->setTimerCallback(this, &onTimer);
|
||||
|
||||
// General MIDI System On message
|
||||
// Resets all GM devices to default settings
|
||||
_driver->sysEx((const byte *)"\x7E\x7F\x09\x01", 4);
|
||||
g_system->delayMillis(20);
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -562,11 +562,11 @@ Common::Error AGOSEngine::init() {
|
||||
|
||||
_driver = MidiDriver::createMidi(dev);
|
||||
|
||||
if (_nativeMT32) {
|
||||
if (_nativeMT32)
|
||||
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
||||
}
|
||||
|
||||
_midi.mapMT32toGM (getGameType() != GType_SIMON2 && !_nativeMT32);
|
||||
_midi.setNativeMT32(_nativeMT32);
|
||||
_midi.mapMT32toGM(getGameType() != GType_SIMON2 && !_nativeMT32);
|
||||
|
||||
_midi.setDriver(_driver);
|
||||
|
||||
|
@ -77,10 +77,10 @@ int MidiPlayer::open() {
|
||||
return ret;
|
||||
_driver->setTimerCallback(this, &onTimer);
|
||||
|
||||
// General MIDI System On message
|
||||
// Resets all GM devices to default settings
|
||||
_driver->sysEx((const byte *)"\x7E\x7F\x09\x01", 4);
|
||||
g_system->delayMillis(20);
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ protected:
|
||||
MidiDriver *_driver;
|
||||
bool _map_mt32_to_gm;
|
||||
bool _passThrough;
|
||||
bool _nativeMT32;
|
||||
|
||||
MusicInfo _music;
|
||||
MusicInfo _sfx;
|
||||
@ -97,6 +98,7 @@ public:
|
||||
void loadS1D(Common::File *in, bool sfx = false);
|
||||
|
||||
void mapMT32toGM(bool map);
|
||||
void setNativeMT32(bool nativeMT32) { _nativeMT32 = nativeMT32; }
|
||||
void setLoop(bool loop);
|
||||
void startTrack(int track);
|
||||
void queueTrack(int track, bool loop);
|
||||
|
@ -170,6 +170,7 @@ int DraciEngine::init() {
|
||||
|
||||
_music = new MusicPlayer(_midiDriver, musicPathMask);
|
||||
_music->setNativeMT32(native_mt32);
|
||||
_music->open();
|
||||
//_music->setAdLib(adlib);
|
||||
|
||||
// Load the game's fonts
|
||||
|
@ -40,13 +40,8 @@ MusicPlayer::MusicPlayer(MidiDriver *driver, const char *pathMask) : _parser(0),
|
||||
memset(_channel, 0, sizeof(_channel));
|
||||
memset(_channelVolume, 255, sizeof(_channelVolume));
|
||||
_masterVolume = 0;
|
||||
this->open();
|
||||
_smfParser = MidiParser::createParser_SMF();
|
||||
_midiMusicData = NULL;
|
||||
|
||||
// TODO: Load cmf.ins with the instrument table. It seems that an
|
||||
// interface for such an operation is supported for AdLib. Maybe for
|
||||
// this card, setting instruments is necessary.
|
||||
}
|
||||
|
||||
MusicPlayer::~MusicPlayer() {
|
||||
@ -89,6 +84,15 @@ int MusicPlayer::open() {
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
// TODO: Load cmf.ins with the instrument table. It seems that an
|
||||
// interface for such an operation is supported for AdLib. Maybe for
|
||||
// this card, setting instruments is necessary.
|
||||
|
||||
_driver->setTimerCallback(this, &onTimer);
|
||||
return 0;
|
||||
}
|
||||
|
@ -427,10 +427,14 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName)
|
||||
setTimbreAD(9, _timbres[i]);
|
||||
}
|
||||
} else if ((MidiDriver::getMusicType(dev) == MT_MT32) || ConfMan.getBool("native_mt32")) {
|
||||
_driver->sendMT32Reset();
|
||||
|
||||
// MT-32
|
||||
_musicType = MT_MT32;
|
||||
loadTimbres(gtlName + ".mt");
|
||||
} else {
|
||||
_driver->sendGMReset();
|
||||
|
||||
// GM
|
||||
_musicType = 0;
|
||||
}
|
||||
|
@ -63,8 +63,12 @@ SoundManager::SoundManager() {
|
||||
_driver = NULL;
|
||||
|
||||
} else {
|
||||
if (_nativeMT32)
|
||||
if (_nativeMT32) {
|
||||
_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
||||
_driver->sendMT32Reset();
|
||||
} else {
|
||||
_driver->sendGMReset();
|
||||
}
|
||||
|
||||
for (index = 0; index < NUM_CHANNELS; ++index) {
|
||||
_channelsInner[index].midiChannel = _driver->allocateChannel();
|
||||
|
@ -107,6 +107,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
|
||||
|
||||
_music = new MusicPlayer(driver);
|
||||
_music->setNativeMT32(native_mt32);
|
||||
_music->open();
|
||||
//_music->setAdLib(adlib);
|
||||
|
||||
// Set default sound frequency
|
||||
|
@ -40,7 +40,6 @@ namespace Made {
|
||||
MusicPlayer::MusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) {
|
||||
memset(_channel, 0, sizeof(_channel));
|
||||
_masterVolume = 0;
|
||||
this->open();
|
||||
_xmidiParser = MidiParser::createParser_XMIDI();
|
||||
_smfParser = MidiParser::createParser_SMF();
|
||||
}
|
||||
@ -81,6 +80,11 @@ int MusicPlayer::open() {
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
_driver->setTimerCallback(this, &onTimer);
|
||||
return 0;
|
||||
}
|
||||
|
@ -82,6 +82,11 @@ MidiMusic::MidiMusic(QueenEngine *vm)
|
||||
_driver->open();
|
||||
_driver->setTimerCallback(this, &timerCallback);
|
||||
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
_parser = MidiParser::createParser_SMF();
|
||||
_parser->setMidiDriver(this);
|
||||
_parser->setTimerRate(_driver->getBaseTempo());
|
||||
|
@ -60,6 +60,19 @@ MusicDriver::~MusicDriver() {
|
||||
delete _driver;
|
||||
}
|
||||
|
||||
int MusicDriver::open() {
|
||||
int retValue = _driver->open();
|
||||
if (retValue)
|
||||
return retValue;
|
||||
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MusicDriver::setVolume(int volume) {
|
||||
volume = CLIP(volume, 0, 255);
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
void setGM(bool isGM) { _isGM = isGM; }
|
||||
|
||||
//MidiDriver interface implementation
|
||||
int open() { return _driver->open(); }
|
||||
int open();
|
||||
void close() { _driver->close(); }
|
||||
void send(uint32 b);
|
||||
|
||||
|
@ -44,6 +44,7 @@ GmMusic::GmMusic(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) {
|
||||
error("Can't open midi device. Errorcode: %d", midiRes);
|
||||
_timerCount = 0;
|
||||
_midiDrv->setTimerCallback(this, passTimerFunc);
|
||||
_midiDrv->sendGMReset();
|
||||
}
|
||||
|
||||
GmMusic::~GmMusic() {
|
||||
|
@ -44,6 +44,7 @@ MT32Music::MT32Music(MidiDriver *pMidiDrv, Disk *pDisk) : MusicBase(pDisk) {
|
||||
error("Can't open midi device. Errorcode: %d",midiRes);
|
||||
_timerCount = 0;
|
||||
_midiDrv->setTimerCallback(this, passTimerFunc);
|
||||
_midiDrv->sendMT32Reset();
|
||||
}
|
||||
|
||||
MT32Music::~MT32Music() {
|
||||
|
@ -867,6 +867,11 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc)
|
||||
//_midiMusic->setNativeMT32(native_mt32);
|
||||
//_midiMusic->setAdLib(adlib);
|
||||
|
||||
if (native_mt32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
|
||||
_musicVolume = ConfMan.getInt("music_volume");
|
||||
|
||||
_sound = new SoundManager(this);
|
||||
|
@ -101,6 +101,11 @@ int MidiPlayer::open() {
|
||||
_parser->setMidiDriver(this);
|
||||
_parser->setTimerRate(_driver->getBaseTempo());
|
||||
_driver->setTimerCallback(this, &timerCallback);
|
||||
|
||||
if (_nativeMT32)
|
||||
_driver->sendMT32Reset();
|
||||
else
|
||||
_driver->sendGMReset();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -306,3 +306,16 @@ MidiDriver::DeviceHandle MidiDriver::getDeviceHandle(const Common::String &ident
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MidiDriver::sendMT32Reset() {
|
||||
static const byte resetSysEx[] = { 0x41, 0x10, 0x16, 0x12, 0x7F, 0x00, 0x00, 0x01, 0x00 };
|
||||
sysEx(resetSysEx, sizeof(resetSysEx));
|
||||
g_system->delayMillis(100);
|
||||
}
|
||||
|
||||
void MidiDriver::sendGMReset() {
|
||||
static const byte resetSysEx[] = { 0x7E, 0x7F, 0x09, 0x01 };
|
||||
sysEx(resetSysEx, sizeof(resetSysEx));
|
||||
g_system->delayMillis(100);
|
||||
}
|
||||
|
||||
|
@ -215,6 +215,16 @@ public:
|
||||
send(0xB0 | channel, 100, 127);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a Roland MT-32 reset sysEx to the midi device.
|
||||
*/
|
||||
void sendMT32Reset();
|
||||
|
||||
/**
|
||||
* Send a General MIDI reset sysEx to the midi device.
|
||||
*/
|
||||
void sendGMReset();
|
||||
|
||||
/**
|
||||
* Transmit a sysEx to the midi device.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user