GROOVIE: Remove dead music code
The Groovie engine implemented some functionality which was later reimplemented in the generic Miles drivers. These are now used by the engine, but the old code is still present. I've removed this to clean up the audio code.
This commit is contained in:
parent
848d8315a6
commit
0856c04bfa
2 changed files with 20 additions and 337 deletions
|
@ -399,42 +399,30 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName)
|
|||
musicType = MT_MT32;
|
||||
_driver = NULL;
|
||||
|
||||
// new Miles Audio support, to disable set milesAudioEnabled to false
|
||||
_milesAudioMode = false;
|
||||
bool milesAudioEnabled = true;
|
||||
|
||||
_musicType = 0;
|
||||
|
||||
if (milesAudioEnabled) {
|
||||
// 7th Guest uses FAT.AD/FAT.OPL/FAT.MT
|
||||
// 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 = _milesMidiDriver = Audio::MidiDriver_Miles_MIDI_create(musicType, gtlName + ".MT");
|
||||
break;
|
||||
case MT_GM:
|
||||
_driver = _milesMidiDriver = Audio::MidiDriver_Miles_MIDI_create(musicType, "");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_musicType = musicType;
|
||||
}
|
||||
|
||||
if (_driver) {
|
||||
_milesAudioMode = true;
|
||||
}
|
||||
|
||||
if (!_driver) {
|
||||
// No driver yet? create a generic one
|
||||
// 7th Guest uses FAT.AD/FAT.OPL/FAT.MT
|
||||
// 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 = _milesMidiDriver = Audio::MidiDriver_Miles_MIDI_create(musicType, gtlName + ".MT");
|
||||
break;
|
||||
case MT_GM:
|
||||
_driver = _milesMidiDriver = Audio::MidiDriver_Miles_MIDI_create(musicType, "");
|
||||
break;
|
||||
case MT_NULL:
|
||||
_driver = MidiDriver::createMidi(dev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
_musicType = musicType;
|
||||
|
||||
assert(_driver);
|
||||
|
||||
|
@ -450,99 +438,6 @@ MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName)
|
|||
|
||||
// Set the timer rate
|
||||
_midiParser->setTimerRate(_driver->getBaseTempo());
|
||||
|
||||
// Initialize the channel banks
|
||||
for (int i = 0; i < 0x10; i++) {
|
||||
_chanBanks[i] = 0;
|
||||
}
|
||||
|
||||
if (_milesAudioMode)
|
||||
return;
|
||||
|
||||
// Load the Global Timbre Library
|
||||
if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
|
||||
// MIDI through AdLib
|
||||
_musicType = MT_ADLIB;
|
||||
loadTimbres(gtlName + ".ad");
|
||||
|
||||
// Setup the percussion channel
|
||||
for (uint i = 0; i < _timbres.size(); i++) {
|
||||
if (_timbres[i].bank == 0x7F)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
MusicPlayerXMI::~MusicPlayerXMI() {
|
||||
//~MusicPlayer();
|
||||
|
||||
// Unload the timbres
|
||||
clearTimbres();
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::send(uint32 b) {
|
||||
if (_milesAudioMode) {
|
||||
MusicPlayerMidi::send(b);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 bytesToSend = b;
|
||||
if ((b & 0xFFF0) == 0x72B0) { // XMIDI Patch Bank Select 114
|
||||
// From AIL2's documentation: XMIDI Patch Bank Select controller (114)
|
||||
// selects a bank to be used when searching the next patches
|
||||
byte chan = b & 0xF;
|
||||
byte bank = (b >> 16) & 0xFF;
|
||||
|
||||
debugC(5, kDebugMIDI, "Groovie::Music: Selecting bank %X for channel %X", bank, chan);
|
||||
_chanBanks[chan] = bank;
|
||||
return;
|
||||
} else if ((b & 0xF0) == 0xC0) { // Program change
|
||||
// We intercept the program change when using AdLib or MT32 drivers,
|
||||
// since we have custom timbres for them. The command is sent
|
||||
// unchanged to GM drivers.
|
||||
byte chan = b & 0xF;
|
||||
byte patch = (b >> 8) & 0xFF;
|
||||
if (_musicType != 0) {
|
||||
|
||||
debugC(5, kDebugMIDI, "Groovie::Music: Setting custom patch %X from bank %X to channel %X", patch, _chanBanks[chan], chan);
|
||||
|
||||
// Try to find the requested patch from the previously
|
||||
// specified bank
|
||||
int numTimbres = _timbres.size();
|
||||
for (int i = 0; i < numTimbres; i++) {
|
||||
if ((_timbres[i].bank == _chanBanks[chan]) &&
|
||||
(_timbres[i].patch == patch)) {
|
||||
if (_musicType == MT_ADLIB) {
|
||||
setTimbreAD(chan, _timbres[i]);
|
||||
} else if (_musicType == MT_MT32) {
|
||||
setTimbreMT(chan, _timbres[i]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here we couldn't find the patch, and the
|
||||
// received message will be sent unchanged.
|
||||
} else if (chan == 0x9) {
|
||||
// GM program change on the rhythm channel (drumkit selection).
|
||||
// Apply drumkit fallback to correct invalid drumkit numbers.
|
||||
byte correctedPatch = _driver->_gsDrumkitFallbackMap[patch];
|
||||
debugC(5, kDebugMIDI, "Groovie::Music: Selected drumkit %X (requested %X)", correctedPatch, patch);
|
||||
bytesToSend = 0xC0 | chan | (correctedPatch << 8);
|
||||
}
|
||||
}
|
||||
MusicPlayerMidi::send(bytesToSend);
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::send(int8 source, uint32 b) {
|
||||
|
@ -596,197 +491,6 @@ void MusicPlayerXMI::unload() {
|
|||
}
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
// Does it exist?
|
||||
if (!Common::File::exists(filename)) {
|
||||
error("Groovie::Music: %s not found", filename.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Open the GTL
|
||||
Common::File *gtl = new Common::File();
|
||||
if (!gtl->open(filename.c_str())) {
|
||||
delete gtl;
|
||||
error("Groovie::Music: Couldn't open %s", filename.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Clear the old timbres before loading the new ones
|
||||
clearTimbres();
|
||||
|
||||
// Get the list of timbres
|
||||
while (true) {
|
||||
Timbre t;
|
||||
t.patch = gtl->readByte();
|
||||
t.bank = gtl->readByte();
|
||||
if ((t.patch == 0xFF) && (t.bank == 0xFF)) {
|
||||
// End of list
|
||||
break;
|
||||
}
|
||||
// We temporarily use the size field to store the offset
|
||||
t.size = gtl->readUint32LE();
|
||||
|
||||
// Add it to the list
|
||||
_timbres.push_back(t);
|
||||
}
|
||||
|
||||
// Read the timbres
|
||||
for (unsigned int i = 0; i < _timbres.size(); i++) {
|
||||
// Seek to the start of the timbre
|
||||
gtl->seek(_timbres[i].size);
|
||||
|
||||
// Read the size
|
||||
_timbres[i].size = gtl->readUint16LE() - 2;
|
||||
|
||||
// Allocate memory for the timbre data
|
||||
_timbres[i].data = new byte[_timbres[i].size];
|
||||
|
||||
// Read the timbre data
|
||||
gtl->read(_timbres[i].data, _timbres[i].size);
|
||||
debugC(5, kDebugMIDI, "Groovie::Music: Loaded patch %x in bank %x with size %d",
|
||||
_timbres[i].patch, _timbres[i].bank, _timbres[i].size);
|
||||
}
|
||||
|
||||
// Close the file
|
||||
delete gtl;
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::clearTimbres() {
|
||||
// Delete the allocated data
|
||||
int num = _timbres.size();
|
||||
for (int i = 0; i < num; i++) {
|
||||
delete[] _timbres[i].data;
|
||||
}
|
||||
|
||||
// Erase the array entries
|
||||
_timbres.clear();
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::setTimbreAD(byte channel, const Timbre &timbre) {
|
||||
// Verify the timbre size
|
||||
if (timbre.size != 12) {
|
||||
error("Groovie::Music: Invalid size for an AdLib timbre: %d", timbre.size);
|
||||
}
|
||||
|
||||
// Prepare the AdLib Instrument array from the GTL entry
|
||||
//
|
||||
// struct AdLibInstrument used by our AdLib MIDI synth is 30 bytes.
|
||||
// Since we pass data + 2 for non percussion instruments we need to
|
||||
// have a buffer of size 32, so there are no invalid memory reads,
|
||||
// when setting up an AdLib instrument.
|
||||
byte data[32];
|
||||
memset(data, 0, sizeof(data));
|
||||
|
||||
data[2] = timbre.data[1]; // mod_characteristic
|
||||
data[3] = timbre.data[2] ^ 0x3F; // mod_scalingOutputLevel
|
||||
data[4] = ~timbre.data[3]; // mod_attackDecay
|
||||
data[5] = ~timbre.data[4]; // mod_sustainRelease
|
||||
data[6] = timbre.data[5]; // mod_waveformSelect
|
||||
data[7] = timbre.data[7]; // car_characteristic
|
||||
data[8] = timbre.data[8] ^ 0x3F; // car_scalingOutputLevel
|
||||
data[9] = ~timbre.data[9]; // car_attackDecay
|
||||
data[10] = ~timbre.data[10]; // car_sustainRelease
|
||||
data[11] = timbre.data[11]; // car_waveformSelect
|
||||
data[12] = timbre.data[6]; // feedback
|
||||
|
||||
// Send the instrument to the driver
|
||||
if (timbre.bank == 0x7F) {
|
||||
// This is a Percussion instrument, this will always be set on the same note
|
||||
data[0] = timbre.patch;
|
||||
|
||||
// From AIL2's documentation: If the instrument is to be played in MIDI
|
||||
// channel 10, num specifies its desired absolute MIDI note number.
|
||||
data[1] = timbre.data[0];
|
||||
|
||||
_driver->getPercussionChannel()->sysEx_customInstrument('ADLP', data);
|
||||
} else {
|
||||
// Some tweaks for non-percussion instruments
|
||||
byte mult1 = timbre.data[1] & 0xF;
|
||||
if (mult1 < 4)
|
||||
mult1 = 1 << mult1;
|
||||
data[2] = (timbre.data[1] & 0xF0) + (mult1 & 0xF);
|
||||
byte mult2 = timbre.data[7] & 0xF;
|
||||
if (mult2 < 4)
|
||||
mult2 = 1 << mult2;
|
||||
data[7] = (timbre.data[7] & 0xF0) + (mult2 & 0xF);
|
||||
// TODO: Fix CHARACTERISTIC: 0xF0: pitch_vib, amp_vib, sustain_sound, env_scaling 0xF: freq_mult
|
||||
// TODO: Fix KSL_TL: 0xC: key_scale_lvl 0x3F: out_lvl
|
||||
|
||||
// From AIL2's documentation: num specifies the number of semitones
|
||||
// by which to transpose notes played with the instrument.
|
||||
if (timbre.data[0] != 0)
|
||||
warning("Groovie::Music: AdLib instrument's transposing not supported");
|
||||
|
||||
_driver->sysEx_customInstrument(channel, 'ADL ', data + 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "common/pack-start.h" // START STRUCT PACKING
|
||||
|
||||
struct RolandInstrumentSysex {
|
||||
byte roland_id;
|
||||
byte device_id;
|
||||
byte model_id;
|
||||
byte command;
|
||||
byte address[3];
|
||||
byte instrument[0xF6];
|
||||
byte checksum;
|
||||
} PACKED_STRUCT;
|
||||
|
||||
#include "common/pack-end.h" // END STRUCT PACKING
|
||||
|
||||
void setRolandInstrument(MidiDriver *drv, byte channel, byte *instrument) {
|
||||
RolandInstrumentSysex sysex;
|
||||
memcpy(&sysex.instrument, instrument, 0xF6);
|
||||
|
||||
// Show the timbre name as extra debug information
|
||||
Common::String name((char *)instrument, 10);
|
||||
debugC(5, kDebugMIDI, "Groovie::Music: Setting MT32 timbre '%s' to channel %d", name.c_str(), channel);
|
||||
|
||||
sysex.roland_id = 0x41;
|
||||
sysex.device_id = channel; // Unit#
|
||||
sysex.model_id = 0x16; // MT32
|
||||
sysex.command = 0x12; // Data set
|
||||
|
||||
// Remap instrument to appropriate address space.
|
||||
int address = 0x008000;
|
||||
sysex.address[0] = (address >> 14) & 0x7F;
|
||||
sysex.address[1] = (address >> 7) & 0x7F;
|
||||
sysex.address[2] = (address ) & 0x7F;
|
||||
|
||||
// Compute the checksum.
|
||||
byte checksum = 0;
|
||||
byte *ptr = sysex.address;
|
||||
for (int i = 4; i < (int)sizeof(RolandInstrumentSysex) - 1; ++i)
|
||||
checksum -= *ptr++;
|
||||
sysex.checksum = checksum & 0x7F;
|
||||
|
||||
// Send sysex
|
||||
drv->sysEx((byte *)&sysex, sizeof(RolandInstrumentSysex));
|
||||
|
||||
|
||||
// Wait the time it takes to send the SysEx data
|
||||
uint32 delay = (sizeof(RolandInstrumentSysex) + 2) * 1000 / 3125;
|
||||
|
||||
// Plus an additional delay for the MT-32 rev00
|
||||
delay += 40;
|
||||
|
||||
g_system->delayMillis(delay);
|
||||
}
|
||||
|
||||
void MusicPlayerXMI::setTimbreMT(byte channel, const Timbre &timbre) {
|
||||
// Verify the timbre size
|
||||
if (timbre.size != 0xF6)
|
||||
error("Groovie::Music: Invalid size for an MT-32 timbre: %d", timbre.size);
|
||||
|
||||
setRolandInstrument(_driver, channel, timbre.data);
|
||||
}
|
||||
|
||||
|
||||
// MusicPlayerMac_t7g
|
||||
|
||||
MusicPlayerMac_t7g::MusicPlayerMac_t7g(GroovieEngine *vm) : MusicPlayerMidi(vm) {
|
||||
|
|
|
@ -125,9 +125,7 @@ protected:
|
|||
class MusicPlayerXMI : public MusicPlayerMidi, public Audio::MidiDriver_Miles_Xmidi_Timbres {
|
||||
public:
|
||||
MusicPlayerXMI(GroovieEngine *vm, const Common::String >lName);
|
||||
~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;
|
||||
void processXMIDITimbreChunk(const byte *timbreListPtr, uint32 timbreListSize) override {
|
||||
|
@ -142,29 +140,10 @@ protected:
|
|||
void unload() override;
|
||||
|
||||
private:
|
||||
// Channel banks
|
||||
byte _chanBanks[0x10];
|
||||
|
||||
// Output music type
|
||||
uint8 _musicType;
|
||||
|
||||
bool _milesAudioMode;
|
||||
Audio::MidiDriver_Miles_Midi *_milesMidiDriver;
|
||||
|
||||
// Timbres
|
||||
class Timbre {
|
||||
public:
|
||||
Timbre() : data(NULL), patch(0), bank(0), size(0) {}
|
||||
byte patch;
|
||||
byte bank;
|
||||
uint32 size;
|
||||
byte *data;
|
||||
};
|
||||
Common::Array<Timbre> _timbres;
|
||||
void loadTimbres(const Common::String &filename);
|
||||
void clearTimbres();
|
||||
void setTimbreAD(byte channel, const Timbre &timbre);
|
||||
void setTimbreMT(byte channel, const Timbre &timbre);
|
||||
};
|
||||
|
||||
class MusicPlayerMac_t7g : public MusicPlayerMidi {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue