mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
GROOVIE: Use new Miles MIDI driver functionality
This adds using the updated Miles MIDI driver for GM music and using the driver for source volume scaling. This reduces the amount of MIDI volume messages when fading, because they are now only sent on active MIDI channels and if they are different from the current channel volume. This fixes problems with hardware MIDI devices like the MT-32 and SC-55, which have trouble dealing with the high number of messages.
This commit is contained in:
parent
580a7e6568
commit
dd0090dc7a
@ -385,11 +385,14 @@ bool MusicPlayerMidi::loadParser(Common::SeekableReadStream *stream, bool loop)
|
||||
// MusicPlayerXMI
|
||||
|
||||
MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName) :
|
||||
MusicPlayerMidi(vm) {
|
||||
MusicPlayerMidi(vm),
|
||||
_milesMidiDriver(NULL) {
|
||||
|
||||
// Create the driver
|
||||
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
|
||||
MusicType musicType = MidiDriver::getMusicType(dev);
|
||||
if (musicType == MT_GM && ConfMan.getBool("native_mt32"))
|
||||
musicType = MT_MT32;
|
||||
_driver = NULL;
|
||||
|
||||
// new Miles Audio support, to disable set milesAudioEnabled to false
|
||||
@ -404,24 +407,22 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName)
|
||||
// 11th Hour uses SAMPLE.AD/SAMPLE.OPL/SAMPLE.MT
|
||||
switch (musicType) {
|
||||
case MT_ADLIB:
|
||||
// TODO Would be nice if the Miles AdLib and MIDI drivers shared
|
||||
// a common interface, then we can use only _milesMidiDriver in
|
||||
// this class.
|
||||
_driver = Audio::MidiDriver_Miles_AdLib_create(gtlName + ".AD", gtlName + ".OPL");
|
||||
break;
|
||||
case MT_MT32:
|
||||
_driver = Audio::MidiDriver_Miles_MT32_create(gtlName + ".MT");
|
||||
_driver = _milesMidiDriver = Audio::MidiDriver_Miles_MIDI_create(musicType, gtlName + ".MT");
|
||||
newTimbreListProc = Audio::MidiDriver_Miles_MT32_processXMIDITimbreChunk;
|
||||
break;
|
||||
case MT_GM:
|
||||
if (ConfMan.getBool("native_mt32")) {
|
||||
_driver = Audio::MidiDriver_Miles_MT32_create(gtlName + ".MT");
|
||||
musicType = MT_MT32;
|
||||
}
|
||||
_driver = _milesMidiDriver = Audio::MidiDriver_Miles_MIDI_create(musicType, "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (musicType == MT_MT32) {
|
||||
newTimbreListProc = Audio::MidiDriver_Miles_MT32_processXMIDITimbreChunk;
|
||||
}
|
||||
_musicType = musicType;
|
||||
}
|
||||
|
||||
if (_driver) {
|
||||
@ -436,9 +437,11 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName)
|
||||
assert(_driver);
|
||||
|
||||
// Create the parser
|
||||
_midiParser = MidiParser::createParser_XMIDI(NULL, NULL, newTimbreListProc, _driver);
|
||||
_midiParser = MidiParser::createParser_XMIDI(NULL, NULL, newTimbreListProc, _milesMidiDriver, 0);
|
||||
|
||||
_driver->open(); // TODO: Handle return value != 0 (indicating an error)
|
||||
int result = _driver->open();
|
||||
if (result > 0 && result != MidiDriver::MERR_ALREADY_OPEN)
|
||||
error("Opening MidiDriver failed with error code %i", result);
|
||||
|
||||
// Set the parser's driver
|
||||
_midiParser->setMidiDriver(this);
|
||||
@ -540,6 +543,33 @@ void MusicPlayerXMI::send(uint32 b) {
|
||||
MusicPlayerMidi::send(bytesToSend);
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::send(int8 source, uint32 b) {
|
||||
if (_milesMidiDriver) {
|
||||
_milesMidiDriver->send(source, b);
|
||||
} else {
|
||||
MusicPlayerMidi::send(b);
|
||||
}
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::metaEvent(int8 source, byte type, byte *data, uint16 length) {
|
||||
if (_milesMidiDriver) {
|
||||
if (type == 0x2F) // End Of Track
|
||||
MusicPlayerMidi::endTrack();
|
||||
_milesMidiDriver->metaEvent(source, type, data, length);
|
||||
} else {
|
||||
MusicPlayerMidi::metaEvent(type, data, length);
|
||||
}
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::updateVolume() {
|
||||
if (_milesMidiDriver) {
|
||||
uint16 val = (_userVolume * _gameVolume) / 100;
|
||||
_milesMidiDriver->setSourceVolume(0, val);
|
||||
} else {
|
||||
MusicPlayerMidi::updateVolume();
|
||||
}
|
||||
}
|
||||
|
||||
bool MusicPlayerXMI::load(uint32 fileref, bool loop) {
|
||||
debugC(1, kDebugMIDI, "Groovie::Music: Starting the playback of song: %04X", fileref);
|
||||
|
||||
@ -553,6 +583,13 @@ bool MusicPlayerXMI::load(uint32 fileref, bool loop) {
|
||||
return loadParser(file, loop);
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::unload() {
|
||||
MusicPlayerMidi::unload();
|
||||
if (_milesMidiDriver) {
|
||||
_milesMidiDriver->deinitSource(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::loadTimbres(const Common::String &filename) {
|
||||
// Load the Global Timbre Library format as documented in AIL2
|
||||
debugC(1, kDebugMIDI, "Groovie::Music: Loading the GTL file %s", filename.c_str());
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "common/mutex.h"
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/mixer.h"
|
||||
#include "audio/miles.h"
|
||||
|
||||
class MidiParser;
|
||||
|
||||
@ -107,8 +108,6 @@ private:
|
||||
byte _chanVolumes[0x10];
|
||||
void updateChanVolume(byte channel);
|
||||
|
||||
void endTrack();
|
||||
|
||||
protected:
|
||||
byte *_data;
|
||||
MidiParser *_midiParser;
|
||||
@ -117,6 +116,7 @@ protected:
|
||||
void onTimerInternal() override;
|
||||
void updateVolume() override;
|
||||
void unload() override;
|
||||
void endTrack();
|
||||
|
||||
bool loadParser(Common::SeekableReadStream *stream, bool loop);
|
||||
};
|
||||
@ -127,9 +127,13 @@ public:
|
||||
~MusicPlayerXMI() override;
|
||||
|
||||
void send(uint32 b) override;
|
||||
void send(int8 source, uint32 b) override;
|
||||
void metaEvent(int8 source, byte type, byte *data, uint16 length) override;
|
||||
|
||||
protected:
|
||||
void updateVolume() override;
|
||||
bool load(uint32 fileref, bool loop) override;
|
||||
void unload() override;
|
||||
|
||||
private:
|
||||
// Channel banks
|
||||
@ -139,6 +143,7 @@ private:
|
||||
uint8 _musicType;
|
||||
|
||||
bool _milesAudioMode;
|
||||
Audio::MidiDriver_Miles_Midi *_milesMidiDriver;
|
||||
|
||||
// Timbres
|
||||
class Timbre {
|
||||
|
Loading…
Reference in New Issue
Block a user