diff options
Diffstat (limited to 'engines/queen/midiadlib.cpp')
-rw-r--r-- | engines/queen/midiadlib.cpp | 139 |
1 files changed, 29 insertions, 110 deletions
diff --git a/engines/queen/midiadlib.cpp b/engines/queen/midiadlib.cpp index 25175c21d7..f5bc0f4d58 100644 --- a/engines/queen/midiadlib.cpp +++ b/engines/queen/midiadlib.cpp @@ -23,118 +23,29 @@ #include "common/endian.h" #include "common/textconsole.h" -#include "audio/fmopl.h" -#include "audio/softsynth/emumidi.h" +#include "engines/queen/midiadlib.h" namespace Queen { -class AdLibMidiDriver : public MidiDriver_Emulated { -public: - - AdLibMidiDriver(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer) { _adlibWaveformSelect = 0; } - ~AdLibMidiDriver() {} - - // MidiDriver - int open(); - void close(); - void send(uint32 b); - void metaEvent(byte type, byte *data, uint16 length); - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } - - // AudioStream - bool isStereo() const { return false; } - int getRate() const { return _mixer->getOutputRate(); } - - // MidiDriver_Emulated - void generateSamples(int16 *buf, int len); - -private: - - void handleMidiEvent0x90_NoteOn(int channel, int param1, int param2); - void handleSequencerSpecificMetaEvent1(int channel, const uint8 *data); - void handleSequencerSpecificMetaEvent2(uint8 value); - void handleSequencerSpecificMetaEvent3(uint8 value); - - void adlibWrite(uint8 port, uint8 value); - void adlibSetupCard(); - void adlibSetupChannels(int fl); - void adlibResetAmpVibratoRhythm(int am, int vib, int kso); - void adlibResetChannels(); - void adlibSetAmpVibratoRhythm(); - void adlibSetCSMKeyboardSplit(); - void adlibSetNoteMul(int mul); - void adlibSetWaveformSelect(int fl); - void adlibSetPitchBend(int channel, int range); - void adlibPlayNote(int channel); - uint8 adlibPlayNoteHelper(int channel, int note1, int note2, int oct); - void adlibTurnNoteOff(int channel); - void adlibTurnNoteOn(int channel, int note); - void adlibSetupChannelFromSequence(int channel, const uint8 *src, int fl); - void adlibSetupChannel(int channel, const uint16 *src, int fl); - void adlibSetNoteVolume(int channel, int volume); - void adlibSetupChannelHelper(int channel); - void adlibSetChannel0x40(int channel); - void adlibSetChannel0xC0(int channel); - void adlibSetChannel0x60(int channel); - void adlibSetChannel0x80(int channel); - void adlibSetChannel0x20(int channel); - void adlibSetChannel0xE0(int channel); - - FM_OPL *_opl; - int _midiNumberOfChannels; - int _adlibNoteMul; - int _adlibWaveformSelect; - int _adlibAMDepthEq48; - int _adlibVibratoDepthEq14; - int _adlibRhythmEnabled; - int _adlibKeyboardSplitOn; - int _adlibVibratoRhythm; - uint8 _midiChannelsFreqTable[9]; - uint8 _adlibChannelsLevelKeyScalingTable[11]; - uint8 _adlibSetupChannelSequence1[14 * 18]; - uint16 _adlibSetupChannelSequence2[14]; - int16 _midiChannelsNote2Table[9]; - uint8 _midiChannelsNote1Table[9]; - uint8 _midiChannelsOctTable[9]; - uint16 _adlibChannelsVolume[11]; - uint16 _adlibMetaSequenceData[28]; - - static const uint8 _adlibChannelsMappingTable1[]; - static const uint8 _adlibChannelsNoFeedback[]; - static const uint8 _adlibChannelsMappingTable2[]; - static const uint8 _adlibChannelsMappingTable3[]; - static const uint8 _adlibChannelsKeyScalingTable1[]; - static const uint8 _adlibChannelsKeyScalingTable2[]; - static const uint8 _adlibChannelsVolumeTable[]; - static const uint8 _adlibInitSequenceData1[]; - static const uint8 _adlibInitSequenceData2[]; - static const uint8 _adlibInitSequenceData3[]; - static const uint8 _adlibInitSequenceData4[]; - static const uint8 _adlibInitSequenceData5[]; - static const uint8 _adlibInitSequenceData6[]; - static const uint8 _adlibInitSequenceData7[]; - static const uint8 _adlibInitSequenceData8[]; - static const int16 _midiChannelsNoteTable[]; - static const int16 _midiNoteFreqTable[]; -}; - int AdLibMidiDriver::open() { - MidiDriver_Emulated::open(); - _opl = makeAdLibOPL(getRate()); + _isOpen = true; + _opl = OPL::Config::create(); + if (!_opl || !_opl->init()) + error("Failed to create OPL"); + adlibSetupCard(); for (int i = 0; i < 11; ++i) { _adlibChannelsVolume[i] = 0; adlibSetNoteVolume(i, 0); adlibTurnNoteOff(i); } - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + + _opl->start(new Common::Functor0Mem<void, AdLibMidiDriver>(this, &AdLibMidiDriver::onTimer)); return 0; } void AdLibMidiDriver::close() { - _mixer->stopHandle(_mixerSoundHandle); - OPLDestroy(_opl); + delete _opl; } void AdLibMidiDriver::send(uint32 b) { @@ -164,6 +75,11 @@ void AdLibMidiDriver::send(uint32 b) { } } +void AdLibMidiDriver::setVolume(uint32 volume) { + for (int i = 0; i < _midiNumberOfChannels; ++i) + adlibSetChannelVolume(i, volume * 64 / 256 + 64); +} + void AdLibMidiDriver::metaEvent(byte type, byte *data, uint16 length) { int event = 0; if (length > 4 && READ_BE_UINT32(data) == 0x3F00) { @@ -192,9 +108,14 @@ void AdLibMidiDriver::metaEvent(byte type, byte *data, uint16 length) { warning("Unhandled meta event %d len %d", event, length); } -void AdLibMidiDriver::generateSamples(int16 *data, int len) { - memset(data, 0, sizeof(int16) * len); - YM3812UpdateOne(_opl, data, len); +void AdLibMidiDriver::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) { + _adlibTimerProc = timerProc; + _adlibTimerParam = timerParam; +} + +void AdLibMidiDriver::onTimer() { + if (_adlibTimerProc) + (*_adlibTimerProc)(_adlibTimerParam); } void AdLibMidiDriver::handleSequencerSpecificMetaEvent1(int channel, const uint8 *data) { @@ -238,7 +159,7 @@ void AdLibMidiDriver::handleMidiEvent0x90_NoteOn(int channel, int param1, int pa } void AdLibMidiDriver::adlibWrite(uint8 port, uint8 value) { - OPLWriteReg(_opl, port, value); + _opl->writeReg(port, value); } void AdLibMidiDriver::adlibSetupCard() { @@ -253,6 +174,7 @@ void AdLibMidiDriver::adlibSetupCard() { _midiChannelsFreqTable[i] = 0; } memset(_adlibChannelsLevelKeyScalingTable, 127, 11); + memset(_adlibChannelsVolumeTable, 128, 11); adlibSetupChannels(0); adlibResetAmpVibratoRhythm(0, 0, 0); adlibSetNoteMul(1); @@ -448,6 +370,11 @@ void AdLibMidiDriver::adlibSetNoteVolume(int channel, int volume) { } } +void AdLibMidiDriver::adlibSetChannelVolume(int channel, uint8 volume) { + if (channel < (_adlibRhythmEnabled ? 11 : 9)) + _adlibChannelsVolumeTable[channel] = volume; +} + void AdLibMidiDriver::adlibSetupChannelHelper(int channel) { adlibSetAmpVibratoRhythm(); adlibSetCSMKeyboardSplit(); @@ -558,10 +485,6 @@ const uint8 AdLibMidiDriver::_adlibChannelsKeyScalingTable2[] = { 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 16, 255, 14, 255, 17, 255, 13, 255 }; -const uint8 AdLibMidiDriver::_adlibChannelsVolumeTable[] = { - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 -}; - const uint8 AdLibMidiDriver::_adlibInitSequenceData1[] = { 1, 1, 3, 15, 5, 0, 1, 3, 15, 0, 0, 0, 1, 0 }; @@ -617,8 +540,4 @@ const int16 AdLibMidiDriver::_midiNoteFreqTable[] = { -363, -361, -359, -356, -354, -351, -349, -347, -344, -342, -339, -337 }; -MidiDriver *C_Player_CreateAdLibMidiDriver(Audio::Mixer *mixer) { - return new AdLibMidiDriver(mixer); -} - } // End of namespace Queen |