aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/queen/midiadlib.cpp122
-rw-r--r--engines/queen/midiadlib.h130
-rw-r--r--engines/queen/music.cpp8
3 files changed, 148 insertions, 112 deletions
diff --git a/engines/queen/midiadlib.cpp b/engines/queen/midiadlib.cpp
index 4797e5d070..457767a2a0 100644
--- a/engines/queen/midiadlib.cpp
+++ b/engines/queen/midiadlib.cpp
@@ -23,109 +23,10 @@
#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; }
- void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
-
- // AudioStream
- int readBuffer(int16 *data, const int numSamples);
- 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);
-
- void onTimer();
-
- OPL::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];
-
- Common::TimerManager::TimerProc _adlibTimerProc;
- void *_adlibTimerParam;
-
- 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 = OPL::Config::create();
@@ -140,7 +41,7 @@ int AdLibMidiDriver::open() {
}
_opl->start(new Common::Functor0Mem<void, AdLibMidiDriver>(this, &AdLibMidiDriver::onTimer));
- _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
return 0;
}
@@ -176,6 +77,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) {
@@ -278,6 +184,7 @@ void AdLibMidiDriver::adlibSetupCard() {
_midiChannelsFreqTable[i] = 0;
}
memset(_adlibChannelsLevelKeyScalingTable, 127, 11);
+ memset(_adlibChannelsVolumeTable, 128, 11);
adlibSetupChannels(0);
adlibResetAmpVibratoRhythm(0, 0, 0);
adlibSetNoteMul(1);
@@ -473,6 +380,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();
@@ -583,10 +495,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
};
@@ -642,8 +550,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
diff --git a/engines/queen/midiadlib.h b/engines/queen/midiadlib.h
new file mode 100644
index 0000000000..d5590253cb
--- /dev/null
+++ b/engines/queen/midiadlib.h
@@ -0,0 +1,130 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "audio/fmopl.h"
+#include "audio/mididrv.h"
+#include "audio/softsynth/emumidi.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; }
+ void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
+
+ // AudioStream
+ int readBuffer(int16 *data, const int numSamples);
+ bool isStereo() const { return false; }
+ int getRate() const { return _mixer->getOutputRate(); }
+
+ // MidiDriver_Emulated
+ void generateSamples(int16 *buf, int len);
+
+ void setVolume(uint32 volume);
+
+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 adlibSetChannelVolume(int channel, uint8 volume);
+ 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);
+
+ void onTimer();
+
+ OPL::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];
+ uint8 _adlibChannelsVolumeTable[11];
+
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
+ 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 _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[];
+};
+
+} // End of namespace Queen
diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp
index 93d6527622..600956ada5 100644
--- a/engines/queen/music.cpp
+++ b/engines/queen/music.cpp
@@ -23,6 +23,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "queen/midiadlib.h"
#include "queen/music.h"
#include "queen/queen.h"
#include "queen/resource.h"
@@ -33,8 +34,6 @@
namespace Queen {
-extern MidiDriver *C_Player_CreateAdLibMidiDriver(Audio::Mixer *);
-
MidiMusic::MidiMusic(QueenEngine *vm)
: _isPlaying(false), _isLooping(false),
_randomLoop(false), _masterVolume(192),
@@ -69,7 +68,7 @@ MidiMusic::MidiMusic(QueenEngine *vm)
// if (READ_LE_UINT16(_musicData + 2) != infoOffset) {
// defaultAdLibVolume = _musicData[infoOffset];
// }
- _driver = C_Player_CreateAdLibMidiDriver(vm->_mixer);
+ _driver = new AdLibMidiDriver(g_system->getMixer());
} else {
_driver = MidiDriver::createMidi(dev);
if (_nativeMT32) {
@@ -117,6 +116,9 @@ void MidiMusic::setVolume(int volume) {
if (_channelsTable[i])
_channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255);
}
+
+ if (_adlib)
+ static_cast<AdLibMidiDriver*>(_driver)->setVolume(volume);
}
void MidiMusic::playSong(uint16 songNum) {