aboutsummaryrefslogtreecommitdiff
path: root/engines/sherlock
diff options
context:
space:
mode:
authorclone27272015-07-09 01:32:53 -0400
committerclone27272015-07-09 01:32:53 -0400
commitdbc8d3c530dd12cbe2cea4d9099f0ec05fedf6d0 (patch)
tree788548528e72cd7af257fa26b997e8f40b3ce500 /engines/sherlock
parent6b3df0d9669d83eebd94976a9b995620e75445be (diff)
parentbb8132beb82a4f5d5a3f8db0fb9dec08b2965b72 (diff)
downloadscummvm-rg350-dbc8d3c530dd12cbe2cea4d9099f0ec05fedf6d0.tar.gz
scummvm-rg350-dbc8d3c530dd12cbe2cea4d9099f0ec05fedf6d0.tar.bz2
scummvm-rg350-dbc8d3c530dd12cbe2cea4d9099f0ec05fedf6d0.zip
Merge pull request #600 from clone2727/opl_alsa
Add support for OPL output through ALSA
Diffstat (limited to 'engines/sherlock')
-rw-r--r--engines/sherlock/scalpel/drivers/adlib.cpp46
1 files changed, 27 insertions, 19 deletions
diff --git a/engines/sherlock/scalpel/drivers/adlib.cpp b/engines/sherlock/scalpel/drivers/adlib.cpp
index 91641fcccd..29a39f0c39 100644
--- a/engines/sherlock/scalpel/drivers/adlib.cpp
+++ b/engines/sherlock/scalpel/drivers/adlib.cpp
@@ -216,10 +216,11 @@ uint16 frequencyLookUpTable[SHERLOCK_ADLIB_NOTES_COUNT] = {
0x1DE6, 0x1E03, 0x1E22, 0x1E42, 0x1E65, 0x1E89
};
-class MidiDriver_SH_AdLib : public MidiDriver_Emulated {
+class MidiDriver_SH_AdLib : public MidiDriver {
public:
MidiDriver_SH_AdLib(Audio::Mixer *mixer)
- : MidiDriver_Emulated(mixer), _masterVolume(15), _opl(0) {
+ : _masterVolume(15), _opl(0),
+ _adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
memset(_voiceChannelMapping, 0, sizeof(_voiceChannelMapping));
}
virtual ~MidiDriver_SH_AdLib() { }
@@ -230,15 +231,13 @@ public:
void send(uint32 b);
MidiChannel *allocateChannel() { return NULL; }
MidiChannel *getPercussionChannel() { return NULL; }
+ bool isOpen() const { return _isOpen; }
+ uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
- // AudioStream
- bool isStereo() const { return false; }
- int getRate() const { return _mixer->getOutputRate(); }
int getPolyphony() const { return SHERLOCK_ADLIB_VOICES_COUNT; }
bool hasRhythmChannel() const { return false; }
- // MidiDriver_Emulated
- void generateSamples(int16 *buf, int len);
+ virtual void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
void setVolume(byte volume);
virtual uint32 property(int prop, uint32 param);
@@ -261,16 +260,19 @@ private:
OPL::OPL *_opl;
int _masterVolume;
+ Common::TimerManager::TimerProc _adlibTimerProc;
+ void *_adlibTimerParam;
+
+ bool _isOpen;
+
// points to a MIDI channel for each of the new voice channels
byte _voiceChannelMapping[SHERLOCK_ADLIB_VOICES_COUNT];
// stores information about all FM voice channels
adlib_ChannelEntry _channels[SHERLOCK_ADLIB_VOICES_COUNT];
-protected:
void onTimer();
-private:
void resetAdLib();
void resetAdLibOperatorRegisters(byte baseRegister, byte value);
void resetAdLibFMVoiceChannelRegisters(byte baseRegister, byte value);
@@ -285,8 +287,6 @@ private:
};
int MidiDriver_SH_AdLib::open() {
- int rate = _mixer->getOutputRate();
-
debugC(kDebugLevelAdLibDriver, "AdLib: starting driver");
_opl = OPL::Config::create(OPL::Config::kOpl2);
@@ -294,17 +294,18 @@ int MidiDriver_SH_AdLib::open() {
if (!_opl)
return -1;
- _opl->init(rate);
+ _opl->init();
- MidiDriver_Emulated::open();
+ _isOpen = true;
- _mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ _opl->start(new Common::Functor0Mem<void, MidiDriver_SH_AdLib>(this, &MidiDriver_SH_AdLib::onTimer));
return 0;
}
void MidiDriver_SH_AdLib::close() {
- _mixer->stopHandle(_mixerSoundHandle);
+ // Stop the OPL timer
+ _opl->stop();
delete _opl;
}
@@ -318,6 +319,12 @@ void MidiDriver_SH_AdLib::setVolume(byte volume) {
// original driver did this before MIDI data processing on each tick
// we do it atm after MIDI data processing
void MidiDriver_SH_AdLib::onTimer() {
+ if (_adlibTimerProc)
+ (*_adlibTimerProc)(_adlibTimerParam);
+
+ // this should/must get called per tick
+ // original driver did this before MIDI data processing on each tick
+ // we do it atm after MIDI data processing
for (byte FMvoiceChannel = 0; FMvoiceChannel < SHERLOCK_ADLIB_VOICES_COUNT; FMvoiceChannel++) {
if (_channels[FMvoiceChannel].inUse) {
_channels[FMvoiceChannel].inUseTimer++;
@@ -417,10 +424,6 @@ void MidiDriver_SH_AdLib::send(uint32 b) {
}
}
-void MidiDriver_SH_AdLib::generateSamples(int16 *data, int len) {
- _opl->readBuffer(data, len);
-}
-
void MidiDriver_SH_AdLib::noteOn(byte MIDIchannel, byte note, byte velocity) {
int16 oldestInUseChannel = -1;
uint16 oldestInUseTimer = 0;
@@ -627,6 +630,11 @@ uint32 MidiDriver_SH_AdLib::property(int prop, uint32 param) {
return 0;
}
+void MidiDriver_SH_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
+ _adlibTimerProc = timerProc;
+ _adlibTimerParam = timerParam;
+}
+
MidiDriver *MidiDriver_SH_AdLib_create() {
return new MidiDriver_SH_AdLib(g_system->getMixer());
}