mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 06:41:51 +00:00
AUDIO: Remove all AudioStream access to OPL
This commit is contained in:
parent
8bcbcd6c16
commit
bed9da8b9d
@ -188,7 +188,8 @@ bool OPL::_hasInstance = false;
|
||||
EmulatedOPL::EmulatedOPL() :
|
||||
_nextTick(0),
|
||||
_samplesPerTick(0),
|
||||
_baseFreq(0) {
|
||||
_baseFreq(0),
|
||||
_handle(new Audio::SoundHandle()) {
|
||||
}
|
||||
|
||||
EmulatedOPL::~EmulatedOPL() {
|
||||
@ -197,6 +198,8 @@ EmulatedOPL::~EmulatedOPL() {
|
||||
// needs to call stop() or the pointer can still use be used in
|
||||
// the mixer thread at the same time.
|
||||
stop();
|
||||
|
||||
delete _handle;
|
||||
}
|
||||
|
||||
int EmulatedOPL::readBuffer(int16 *buffer, const int numSamples) {
|
||||
@ -232,13 +235,11 @@ int EmulatedOPL::getRate() const {
|
||||
|
||||
void EmulatedOPL::startCallbacks(int timerFrequency) {
|
||||
setCallbackFrequency(timerFrequency);
|
||||
// TODO: Eventually start mixer playback here
|
||||
//g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, _handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
void EmulatedOPL::stopCallbacks() {
|
||||
// TODO: Eventually stop mixer playback here
|
||||
//g_system->getMixer()->stopHandle(*_handle);
|
||||
g_system->getMixer()->stopHandle(*_handle);
|
||||
}
|
||||
|
||||
void EmulatedOPL::setCallbackFrequency(int timerFrequency) {
|
||||
|
@ -23,10 +23,16 @@
|
||||
#ifndef AUDIO_FMOPL_H
|
||||
#define AUDIO_FMOPL_H
|
||||
|
||||
#include "audio/audiostream.h"
|
||||
|
||||
#include "common/func.h"
|
||||
#include "common/ptr.h"
|
||||
#include "common/scummsys.h"
|
||||
|
||||
namespace Audio {
|
||||
class SoundHandle;
|
||||
}
|
||||
|
||||
namespace Common {
|
||||
class String;
|
||||
}
|
||||
@ -148,23 +154,6 @@ public:
|
||||
*/
|
||||
virtual void writeReg(int r, int v) = 0;
|
||||
|
||||
/**
|
||||
* Read up to 'length' samples.
|
||||
*
|
||||
* Data will be in native endianess, 16 bit per sample, signed.
|
||||
* For stereo OPL, buffer will be filled with interleaved
|
||||
* left and right channel samples, starting with a left sample.
|
||||
* Furthermore, the samples in the left and right are summed up.
|
||||
* So if you request 4 samples from a stereo OPL, you will get
|
||||
* a total of two left channel and two right channel samples.
|
||||
*/
|
||||
virtual int readBuffer(int16 *buffer, const int numSamples) = 0;
|
||||
|
||||
/**
|
||||
* Returns whether the setup OPL mode is stereo or not
|
||||
*/
|
||||
virtual bool isStereo() const = 0;
|
||||
|
||||
/**
|
||||
* Start the OPL with callbacks.
|
||||
*/
|
||||
@ -205,17 +194,18 @@ protected:
|
||||
Common::ScopedPtr<TimerCallback> _callback;
|
||||
};
|
||||
|
||||
class EmulatedOPL : public OPL {
|
||||
class EmulatedOPL : public OPL, protected Audio::AudioStream {
|
||||
public:
|
||||
EmulatedOPL();
|
||||
virtual ~EmulatedOPL();
|
||||
|
||||
// OPL API
|
||||
int readBuffer(int16 *buffer, const int numSamples);
|
||||
bool isRunning() const;
|
||||
void setCallbackFrequency(int timerFrequency);
|
||||
|
||||
// AudioStream API
|
||||
int readBuffer(int16 *buffer, const int numSamples);
|
||||
int getRate() const;
|
||||
bool endOfData() const { return false; }
|
||||
|
||||
protected:
|
||||
// OPL API
|
||||
@ -243,6 +233,8 @@ private:
|
||||
|
||||
int _nextTick;
|
||||
int _samplesPerTick;
|
||||
|
||||
Audio::SoundHandle *_handle;
|
||||
};
|
||||
|
||||
} // End of namespace OPL
|
||||
|
@ -116,9 +116,9 @@ uint16 milesAdLibVolumeSensitivityTable[] = {
|
||||
};
|
||||
|
||||
|
||||
class MidiDriver_Miles_AdLib : public MidiDriver_Emulated {
|
||||
class MidiDriver_Miles_AdLib : public MidiDriver {
|
||||
public:
|
||||
MidiDriver_Miles_AdLib(Audio::Mixer *mixer, InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
|
||||
MidiDriver_Miles_AdLib(InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount);
|
||||
virtual ~MidiDriver_Miles_AdLib();
|
||||
|
||||
// MidiDriver
|
||||
@ -128,15 +128,8 @@ public:
|
||||
MidiChannel *allocateChannel() { return NULL; }
|
||||
MidiChannel *getPercussionChannel() { return NULL; }
|
||||
|
||||
// AudioStream
|
||||
int readBuffer(int16 *data, const int numSamples);
|
||||
bool isStereo() const { return _modeStereo; }
|
||||
int getRate() const { return _mixer->getOutputRate(); }
|
||||
int getPolyphony() const { return _modePhysicalFmVoicesCount; }
|
||||
bool hasRhythmChannel() const { return false; }
|
||||
|
||||
// MidiDriver_Emulated
|
||||
void generateSamples(int16 *buf, int len);
|
||||
bool isOpen() const { return _isOpen; }
|
||||
uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
|
||||
|
||||
void setVolume(byte volume);
|
||||
virtual uint32 property(int prop, uint32 param);
|
||||
@ -228,6 +221,8 @@ private:
|
||||
Common::TimerManager::TimerProc _adlibTimerProc;
|
||||
void *_adlibTimerParam;
|
||||
|
||||
bool _isOpen;
|
||||
|
||||
// stores information about all MIDI channels (not the actual OPL FM voice channels!)
|
||||
MidiChannelEntry _midiChannels[MILES_MIDI_CHANNEL_COUNT];
|
||||
|
||||
@ -275,9 +270,9 @@ private:
|
||||
void pitchBendChange(byte MIDIchannel, byte parameter1, byte parameter2);
|
||||
};
|
||||
|
||||
MidiDriver_Miles_AdLib::MidiDriver_Miles_AdLib(Audio::Mixer *mixer, InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount)
|
||||
: MidiDriver_Emulated(mixer), _masterVolume(15), _opl(0),
|
||||
_adlibTimerProc(0), _adlibTimerParam(0) {
|
||||
MidiDriver_Miles_AdLib::MidiDriver_Miles_AdLib(InstrumentEntry *instrumentTablePtr, uint16 instrumentTableCount)
|
||||
: _masterVolume(15), _opl(0),
|
||||
_adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
|
||||
|
||||
_instrumentTablePtr = instrumentTablePtr;
|
||||
_instrumentTableCount = instrumentTableCount;
|
||||
@ -324,10 +319,9 @@ int MidiDriver_Miles_AdLib::open() {
|
||||
|
||||
_opl->init();
|
||||
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, MidiDriver_Miles_AdLib>(this, &MidiDriver_Miles_AdLib::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
|
||||
resetAdLib();
|
||||
|
||||
@ -335,9 +329,8 @@ int MidiDriver_Miles_AdLib::open() {
|
||||
}
|
||||
|
||||
void MidiDriver_Miles_AdLib::close() {
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
|
||||
delete _opl;
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
void MidiDriver_Miles_AdLib::setVolume(byte volume) {
|
||||
@ -444,14 +437,6 @@ void MidiDriver_Miles_AdLib::send(uint32 b) {
|
||||
}
|
||||
}
|
||||
|
||||
void MidiDriver_Miles_AdLib::generateSamples(int16 *data, int len) {
|
||||
// Dummy implementation until we no longer inherit from MidiDriver_Emulated
|
||||
}
|
||||
|
||||
int MidiDriver_Miles_AdLib::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void MidiDriver_Miles_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
|
||||
_adlibTimerProc = timerProc;
|
||||
_adlibTimerParam = timerParam;
|
||||
@ -1283,7 +1268,7 @@ MidiDriver *MidiDriver_Miles_AdLib_create(const Common::String &filenameAdLib, c
|
||||
// Free instrument file/stream data
|
||||
delete[] streamDataPtr;
|
||||
|
||||
return new MidiDriver_Miles_AdLib(g_system->getMixer(), instrumentTablePtr, instrumentTableCount);
|
||||
return new MidiDriver_Miles_AdLib(instrumentTablePtr, instrumentTableCount);
|
||||
}
|
||||
|
||||
} // End of namespace Audio
|
||||
|
@ -927,18 +927,20 @@ static void createLookupTable() {
|
||||
//
|
||||
////////////////////////////////////////
|
||||
|
||||
class MidiDriver_ADLIB : public MidiDriver_Emulated {
|
||||
class MidiDriver_ADLIB : public MidiDriver {
|
||||
friend class AdLibPart;
|
||||
friend class AdLibPercussionChannel;
|
||||
|
||||
public:
|
||||
MidiDriver_ADLIB(Audio::Mixer *mixer);
|
||||
MidiDriver_ADLIB();
|
||||
|
||||
int open();
|
||||
void close();
|
||||
void send(uint32 b);
|
||||
void send(byte channel, uint32 b); // Supports higher than channel 15
|
||||
uint32 property(int prop, uint32 param);
|
||||
bool isOpen() const { return _isOpen; }
|
||||
uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
|
||||
|
||||
void setPitchBendRange(byte channel, uint range);
|
||||
void sysEx_customInstrument(byte channel, uint32 type, const byte *instr);
|
||||
@ -946,12 +948,6 @@ public:
|
||||
MidiChannel *allocateChannel();
|
||||
MidiChannel *getPercussionChannel() { return &_percussion; } // Percussion partially supported
|
||||
|
||||
|
||||
// AudioStream API
|
||||
int readBuffer(int16 *data, const int numSamples);
|
||||
bool isStereo() const { return _opl->isStereo(); }
|
||||
int getRate() const { return _mixer->getOutputRate(); }
|
||||
|
||||
virtual void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
|
||||
|
||||
private:
|
||||
@ -980,7 +976,8 @@ private:
|
||||
AdLibPart _parts[32];
|
||||
AdLibPercussionChannel _percussion;
|
||||
|
||||
void generateSamples(int16 *buf, int len);
|
||||
bool _isOpen;
|
||||
|
||||
void onTimer();
|
||||
void partKeyOn(AdLibPart *part, const AdLibInstrument *instr, byte note, byte velocity, const AdLibInstrument *second, byte pan);
|
||||
void partKeyOff(AdLibPart *part, byte note);
|
||||
@ -1382,8 +1379,7 @@ void AdLibPercussionChannel::sysEx_customInstrument(uint32 type, const byte *ins
|
||||
|
||||
// MidiDriver method implementations
|
||||
|
||||
MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer)
|
||||
: MidiDriver_Emulated(mixer) {
|
||||
MidiDriver_ADLIB::MidiDriver_ADLIB() {
|
||||
uint i;
|
||||
|
||||
_scummSmallHeader = false;
|
||||
@ -1411,13 +1407,14 @@ MidiDriver_ADLIB::MidiDriver_ADLIB(Audio::Mixer *mixer)
|
||||
_opl = 0;
|
||||
_adlibTimerProc = 0;
|
||||
_adlibTimerParam = 0;
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
int MidiDriver_ADLIB::open() {
|
||||
if (_isOpen)
|
||||
return MERR_ALREADY_OPEN;
|
||||
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
|
||||
int i;
|
||||
AdLibVoice *voice;
|
||||
@ -1461,8 +1458,6 @@ int MidiDriver_ADLIB::open() {
|
||||
#endif
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, MidiDriver_ADLIB>(this, &MidiDriver_ADLIB::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1471,7 +1466,8 @@ void MidiDriver_ADLIB::close() {
|
||||
return;
|
||||
_isOpen = false;
|
||||
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
// Stop the OPL timer
|
||||
_opl->stop();
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < ARRAYSIZE(_voices); ++i) {
|
||||
@ -1625,14 +1621,6 @@ void MidiDriver_ADLIB::adlibWriteSecondary(byte reg, byte value) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void MidiDriver_ADLIB::generateSamples(int16 *data, int len) {
|
||||
// Dummy implementation until we no longer inherit from MidiDriver_Emulated
|
||||
}
|
||||
|
||||
int MidiDriver_ADLIB::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void MidiDriver_ADLIB::onTimer() {
|
||||
if (_adlibTimerProc)
|
||||
(*_adlibTimerProc)(_adlibTimerParam);
|
||||
@ -2318,7 +2306,7 @@ MusicDevices AdLibEmuMusicPlugin::getDevices() const {
|
||||
}
|
||||
|
||||
Common::Error AdLibEmuMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const {
|
||||
*mididriver = new MidiDriver_ADLIB(g_system->getMixer());
|
||||
*mididriver = new MidiDriver_ADLIB();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
@ -177,10 +177,6 @@ bool OPL::init() {
|
||||
_emulator->WriteReg(0x105, 1);
|
||||
}
|
||||
|
||||
// FIXME: Remove this once EmulatedOPL is actually controlling playback
|
||||
if (!_callback)
|
||||
start(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,6 @@ bool OPL::init() {
|
||||
|
||||
_opl = MAME::makeAdLibOPL(g_system->getMixer()->getOutputRate());
|
||||
|
||||
// FIXME: Remove this once EmulatedOPL is actually controlling playback
|
||||
start(0);
|
||||
|
||||
return (_opl != 0);
|
||||
}
|
||||
|
||||
|
@ -112,9 +112,9 @@ const uint16 frequencyLookUpTableMusicDrv[12] = {
|
||||
//
|
||||
// I have currently not implemented dynamic channel allocation.
|
||||
|
||||
class MidiDriver_Accolade_AdLib : public MidiDriver_Emulated {
|
||||
class MidiDriver_Accolade_AdLib : public MidiDriver {
|
||||
public:
|
||||
MidiDriver_Accolade_AdLib(Audio::Mixer *mixer);
|
||||
MidiDriver_Accolade_AdLib();
|
||||
virtual ~MidiDriver_Accolade_AdLib();
|
||||
|
||||
// MidiDriver
|
||||
@ -124,15 +124,8 @@ public:
|
||||
MidiChannel *allocateChannel() { return NULL; }
|
||||
MidiChannel *getPercussionChannel() { return NULL; }
|
||||
|
||||
// AudioStream
|
||||
int readBuffer(int16 *data, const int numSamples);
|
||||
bool isStereo() const { return false; }
|
||||
int getRate() const { return _mixer->getOutputRate(); }
|
||||
int getPolyphony() const { return AGOS_ADLIB_VOICES_COUNT; }
|
||||
bool hasRhythmChannel() const { return false; }
|
||||
|
||||
// MidiDriver_Emulated
|
||||
void generateSamples(int16 *buf, int len);
|
||||
bool isOpen() const { return _isOpen; }
|
||||
uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
|
||||
|
||||
void setVolume(byte volume);
|
||||
virtual uint32 property(int prop, uint32 param);
|
||||
@ -176,6 +169,8 @@ private:
|
||||
Common::TimerManager::TimerProc _adlibTimerProc;
|
||||
void *_adlibTimerParam;
|
||||
|
||||
bool _isOpen;
|
||||
|
||||
// points to a MIDI channel for each of the new voice channels
|
||||
byte _voiceChannelMapping[AGOS_ADLIB_VOICES_COUNT];
|
||||
|
||||
@ -196,9 +191,9 @@ private:
|
||||
void noteOff(byte FMvoiceChannel, byte note, bool dontCheckNote);
|
||||
};
|
||||
|
||||
MidiDriver_Accolade_AdLib::MidiDriver_Accolade_AdLib(Audio::Mixer *mixer)
|
||||
: MidiDriver_Emulated(mixer), _masterVolume(15), _opl(0),
|
||||
_adlibTimerProc(0), _adlibTimerParam(0) {
|
||||
MidiDriver_Accolade_AdLib::MidiDriver_Accolade_AdLib()
|
||||
: _masterVolume(15), _opl(0),
|
||||
_adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
|
||||
memset(_channelMapping, 0, sizeof(_channelMapping));
|
||||
memset(_instrumentMapping, 0, sizeof(_instrumentMapping));
|
||||
memset(_instrumentVolumeAdjust, 0, sizeof(_instrumentVolumeAdjust));
|
||||
@ -227,10 +222,9 @@ int MidiDriver_Accolade_AdLib::open() {
|
||||
|
||||
_opl->init();
|
||||
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, MidiDriver_Accolade_AdLib>(this, &MidiDriver_Accolade_AdLib::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
|
||||
|
||||
resetAdLib();
|
||||
|
||||
@ -264,9 +258,8 @@ int MidiDriver_Accolade_AdLib::open() {
|
||||
}
|
||||
|
||||
void MidiDriver_Accolade_AdLib::close() {
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
|
||||
delete _opl;
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
void MidiDriver_Accolade_AdLib::setVolume(byte volume) {
|
||||
@ -374,14 +367,6 @@ void MidiDriver_Accolade_AdLib::send(uint32 b) {
|
||||
}
|
||||
}
|
||||
|
||||
void MidiDriver_Accolade_AdLib::generateSamples(int16 *data, int len) {
|
||||
// Dummy implementation until we no longer inherit from MidiDriver_Emulated
|
||||
}
|
||||
|
||||
int MidiDriver_Accolade_AdLib::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void MidiDriver_Accolade_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
|
||||
_adlibTimerProc = timerProc;
|
||||
_adlibTimerParam = timerParam;
|
||||
@ -886,7 +871,7 @@ MidiDriver *MidiDriver_Accolade_AdLib_create(Common::String driverFilename) {
|
||||
if (!driverData)
|
||||
error("ACCOLADE-ADLIB: error during readDriver()");
|
||||
|
||||
MidiDriver_Accolade_AdLib *driver = new MidiDriver_Accolade_AdLib(g_system->getMixer());
|
||||
MidiDriver_Accolade_AdLib *driver = new MidiDriver_Accolade_AdLib();
|
||||
if (driver) {
|
||||
if (!driver->setupInstruments(driverData, driverDataSize, isMusicDrvFile)) {
|
||||
delete driver;
|
||||
|
@ -101,7 +101,7 @@ struct AdLibSoundInstrument {
|
||||
byte amDepth;
|
||||
};
|
||||
|
||||
class AdLibSoundDriver : public PCSoundDriver, Audio::AudioStream {
|
||||
class AdLibSoundDriver : public PCSoundDriver {
|
||||
public:
|
||||
AdLibSoundDriver(Audio::Mixer *mixer);
|
||||
virtual ~AdLibSoundDriver();
|
||||
@ -112,12 +112,6 @@ public:
|
||||
virtual void stopChannel(int channel);
|
||||
virtual void stopAll();
|
||||
|
||||
// AudioStream interface
|
||||
virtual int readBuffer(int16 *buffer, const int numSamples);
|
||||
virtual bool isStereo() const { return false; }
|
||||
virtual bool endOfData() const { return false; }
|
||||
virtual int getRate() const { return _sampleRate; }
|
||||
|
||||
void initCard();
|
||||
void onTimer();
|
||||
void setupInstrument(const byte *data, int channel);
|
||||
@ -129,9 +123,7 @@ protected:
|
||||
void *_upRef;
|
||||
|
||||
OPL::OPL *_opl;
|
||||
int _sampleRate;
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
|
||||
byte _vibrato;
|
||||
int _channelsVolumeTable[4];
|
||||
@ -283,7 +275,6 @@ void PCSoundDriver::resetChannel(int channel) {
|
||||
AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
|
||||
: _upCb(0), _upRef(0), _mixer(mixer) {
|
||||
|
||||
_sampleRate = _mixer->getOutputRate();
|
||||
_opl = OPL::Config::create();
|
||||
if (!_opl || !_opl->init())
|
||||
error("Failed to create OPL");
|
||||
@ -292,11 +283,9 @@ AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
|
||||
memset(_instrumentsTable, 0, sizeof(_instrumentsTable));
|
||||
initCard();
|
||||
_opl->start(new Common::Functor0Mem<void, AdLibSoundDriver>(this, &AdLibSoundDriver::onTimer), 50);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
AdLibSoundDriver::~AdLibSoundDriver() {
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
delete _opl;
|
||||
}
|
||||
|
||||
@ -346,10 +335,6 @@ void AdLibSoundDriver::stopAll() {
|
||||
_opl->writeReg(0xBD, 0);
|
||||
}
|
||||
|
||||
int AdLibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
|
||||
return _opl->readBuffer(buffer, numSamples);
|
||||
}
|
||||
|
||||
void AdLibSoundDriver::initCard() {
|
||||
_vibrato = 0x20;
|
||||
_opl->writeReg(0xBD, _vibrato);
|
||||
|
@ -108,7 +108,7 @@ struct VolumeEntry {
|
||||
int adjusted;
|
||||
};
|
||||
|
||||
class AdLibSoundDriver : public PCSoundDriver, Audio::AudioStream {
|
||||
class AdLibSoundDriver : public PCSoundDriver {
|
||||
public:
|
||||
AdLibSoundDriver(Audio::Mixer *mixer);
|
||||
virtual ~AdLibSoundDriver();
|
||||
@ -118,12 +118,6 @@ public:
|
||||
virtual void stopChannel(int channel);
|
||||
virtual void stopAll();
|
||||
|
||||
// AudioStream interface
|
||||
virtual int readBuffer(int16 *buffer, const int numSamples);
|
||||
virtual bool isStereo() const { return false; }
|
||||
virtual bool endOfData() const { return false; }
|
||||
virtual int getRate() const { return _sampleRate; }
|
||||
|
||||
void initCard();
|
||||
void onTimer();
|
||||
void setupInstrument(const byte *data, int channel);
|
||||
@ -136,9 +130,7 @@ public:
|
||||
|
||||
protected:
|
||||
OPL::OPL *_opl;
|
||||
int _sampleRate;
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
|
||||
byte _vibrato;
|
||||
VolumeEntry _channelsVolumeTable[5];
|
||||
@ -302,7 +294,6 @@ void PCSoundDriver::syncSounds() {
|
||||
|
||||
AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
|
||||
: _mixer(mixer) {
|
||||
_sampleRate = _mixer->getOutputRate();
|
||||
_opl = OPL::Config::create();
|
||||
if (!_opl || !_opl->init())
|
||||
error("Failed to create OPL");
|
||||
@ -318,11 +309,9 @@ AdLibSoundDriver::AdLibSoundDriver(Audio::Mixer *mixer)
|
||||
_sfxVolume = ConfMan.getBool("sfx_mute") ? 0 : MIN(255, ConfMan.getInt("sfx_volume"));
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, AdLibSoundDriver>(this, &AdLibSoundDriver::onTimer), 50);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
AdLibSoundDriver::~AdLibSoundDriver() {
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
delete _opl;
|
||||
}
|
||||
|
||||
@ -390,10 +379,6 @@ void AdLibSoundDriver::stopAll() {
|
||||
_opl->writeReg(0xBD, 0);
|
||||
}
|
||||
|
||||
int AdLibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
|
||||
return _opl->readBuffer(buffer, numSamples);
|
||||
}
|
||||
|
||||
void AdLibSoundDriver::initCard() {
|
||||
_vibrato = 0x20;
|
||||
_opl->writeReg(0xBD, _vibrato);
|
||||
|
@ -118,8 +118,6 @@ const uint16 AdLib::kHihatParams [kParamCount] = {
|
||||
AdLib::AdLib(Audio::Mixer &mixer, int callbackFreq) : _mixer(&mixer), _opl(0),
|
||||
_toPoll(0), _repCount(0), _first(true), _playing(false), _ended(true), _volume(0) {
|
||||
|
||||
_rate = _mixer->getOutputRate();
|
||||
|
||||
initFreqs();
|
||||
|
||||
createOPL();
|
||||
@ -128,13 +126,9 @@ AdLib::AdLib(Audio::Mixer &mixer, int callbackFreq) : _mixer(&mixer), _opl(0),
|
||||
syncVolume();
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, AdLib>(this, &AdLib::onTimer), callbackFreq);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle,
|
||||
this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
AdLib::~AdLib() {
|
||||
_mixer->stopHandle(_handle);
|
||||
|
||||
delete _opl;
|
||||
}
|
||||
|
||||
@ -168,10 +162,6 @@ void AdLib::createOPL() {
|
||||
}
|
||||
}
|
||||
|
||||
int AdLib::readBuffer(int16 *buffer, const int numSamples) {
|
||||
return _opl->readBuffer(buffer, numSamples);
|
||||
}
|
||||
|
||||
void AdLib::onTimer() {
|
||||
Common::StackLock slock(_mutex);
|
||||
|
||||
@ -218,22 +208,6 @@ void AdLib::onTimer() {
|
||||
}
|
||||
}
|
||||
|
||||
bool AdLib::isStereo() const {
|
||||
return _opl->isStereo();
|
||||
}
|
||||
|
||||
bool AdLib::endOfData() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdLib::endOfStream() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
int AdLib::getRate() const {
|
||||
return _rate;
|
||||
}
|
||||
|
||||
bool AdLib::isPlaying() const {
|
||||
return _playing;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ namespace OPL {
|
||||
namespace Gob {
|
||||
|
||||
/** Base class for a player of an AdLib music format. */
|
||||
class AdLib : public Audio::AudioStream {
|
||||
class AdLib {
|
||||
public:
|
||||
AdLib(Audio::Mixer &mixer, int callbackFrequency);
|
||||
virtual ~AdLib();
|
||||
@ -55,13 +55,6 @@ public:
|
||||
void stopPlay();
|
||||
void syncVolume();
|
||||
|
||||
// AudioStream API
|
||||
int readBuffer(int16 *buffer, const int numSamples);
|
||||
bool isStereo() const;
|
||||
bool endOfData() const;
|
||||
bool endOfStream() const;
|
||||
int getRate() const;
|
||||
|
||||
protected:
|
||||
enum kVoice {
|
||||
kVoiceMelody0 = 0,
|
||||
@ -233,7 +226,6 @@ private:
|
||||
|
||||
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _handle;
|
||||
OPL::OPL *_opl;
|
||||
|
||||
Common::Mutex _mutex;
|
||||
|
@ -57,8 +57,12 @@ uint32 MUSPlayer::pollMusic(bool first) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (first)
|
||||
if (first) {
|
||||
// Set the timer frequency on first run.
|
||||
// Do not set it in rewind() for thread safety reasons.
|
||||
setTimerFrequency((_ticksPerBeat * _tempo) / 60);
|
||||
return *_playPos++;
|
||||
}
|
||||
|
||||
uint16 delay = 0;
|
||||
while (delay == 0) {
|
||||
@ -185,8 +189,6 @@ void MUSPlayer::rewind() {
|
||||
|
||||
setPercussionMode(_soundMode != 0);
|
||||
setPitchRange(_pitchBendRange);
|
||||
|
||||
setTimerFrequency((_ticksPerBeat * _tempo) / 60);
|
||||
}
|
||||
|
||||
bool MUSPlayer::loadSND(Common::SeekableReadStream &snd) {
|
||||
|
@ -55,7 +55,7 @@
|
||||
|
||||
namespace Kyra {
|
||||
|
||||
class AdLibDriver : public Audio::AudioStream {
|
||||
class AdLibDriver {
|
||||
public:
|
||||
AdLibDriver(Audio::Mixer *mixer, int version);
|
||||
~AdLibDriver();
|
||||
@ -70,16 +70,6 @@ public:
|
||||
|
||||
void callback();
|
||||
|
||||
// AudioStream API
|
||||
int readBuffer(int16 *buffer, const int numSamples) {
|
||||
return _adlib->readBuffer(buffer, numSamples);
|
||||
}
|
||||
|
||||
|
||||
bool isStereo() const { return false; }
|
||||
bool endOfData() const { return false; }
|
||||
int getRate() const { return _mixer->getOutputRate(); }
|
||||
|
||||
void setSyncJumpMask(uint16 mask) { _syncJumpMask = mask; }
|
||||
|
||||
void setMusicVolume(uint8 volume);
|
||||
@ -388,7 +378,6 @@ private:
|
||||
|
||||
Common::Mutex _mutex;
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
|
||||
uint8 _musicVolume, _sfxVolume;
|
||||
|
||||
@ -440,11 +429,9 @@ AdLibDriver::AdLibDriver(Audio::Mixer *mixer, int version) {
|
||||
_retrySounds = false;
|
||||
|
||||
_adlib->start(new Common::Functor0Mem<void, AdLibDriver>(this, &AdLibDriver::callback), CALLBACKS_PER_SECOND);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
AdLibDriver::~AdLibDriver() {
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
delete _adlib;
|
||||
_adlib = 0;
|
||||
}
|
||||
|
@ -213,16 +213,12 @@ ASound::ASound(Audio::Mixer *mixer, OPL::OPL *opl, const Common::String &filenam
|
||||
command0();
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, ASound>(this, &ASound::onTimer), CALLBACKS_PER_SECOND);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1,
|
||||
Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
ASound::~ASound() {
|
||||
Common::List<CachedDataEntry>::iterator i;
|
||||
for (i = _dataCache.begin(); i != _dataCache.end(); ++i)
|
||||
delete[] (*i)._data;
|
||||
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
}
|
||||
|
||||
void ASound::validate() {
|
||||
@ -828,20 +824,12 @@ void ASound::updateFNumber() {
|
||||
write2(8, hiReg, val2);
|
||||
}
|
||||
|
||||
int ASound::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void ASound::onTimer() {
|
||||
Common::StackLock slock(_driverMutex);
|
||||
poll();
|
||||
flush();
|
||||
}
|
||||
|
||||
int ASound::getRate() const {
|
||||
return g_system->getMixer()->getOutputRate();
|
||||
}
|
||||
|
||||
void ASound::setVolume(int volume) {
|
||||
_masterVolume = volume;
|
||||
if (!volume)
|
||||
|
@ -145,7 +145,7 @@ struct CachedDataEntry {
|
||||
/**
|
||||
* Base class for the sound player resource files
|
||||
*/
|
||||
class ASound : public Audio::AudioStream {
|
||||
class ASound {
|
||||
private:
|
||||
Common::List<CachedDataEntry> _dataCache;
|
||||
uint16 _randomSeed;
|
||||
@ -282,7 +282,6 @@ protected:
|
||||
public:
|
||||
Audio::Mixer *_mixer;
|
||||
OPL::OPL *_opl;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
AdlibChannel _channels[ADLIB_CHANNEL_COUNT];
|
||||
AdlibChannel *_activeChannelPtr;
|
||||
AdlibChannelData _channelData[11];
|
||||
@ -367,27 +366,6 @@ public:
|
||||
*/
|
||||
CachedDataEntry &getCachedData(byte *pData);
|
||||
|
||||
// AudioStream interface
|
||||
/**
|
||||
* Main buffer read
|
||||
*/
|
||||
virtual int readBuffer(int16 *buffer, const int numSamples);
|
||||
|
||||
/**
|
||||
* Mono sound only
|
||||
*/
|
||||
virtual bool isStereo() const { return false; }
|
||||
|
||||
/**
|
||||
* Data is continuously pushed, so definitive end
|
||||
*/
|
||||
virtual bool endOfData() const { return false; }
|
||||
|
||||
/**
|
||||
* Return sample rate
|
||||
*/
|
||||
virtual int getRate() const;
|
||||
|
||||
/**
|
||||
* Set the volume
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include "audio/fmopl.h"
|
||||
#include "audio/mpu401.h"
|
||||
#include "audio/softsynth/emumidi.h"
|
||||
#include "audio/mididrv.h"
|
||||
|
||||
namespace Parallaction {
|
||||
|
||||
@ -270,11 +270,13 @@ struct MelodicVoice {
|
||||
int8 _octave;
|
||||
};
|
||||
|
||||
class AdLibDriver : public MidiDriver_Emulated {
|
||||
class AdLibDriver : public MidiDriver {
|
||||
public:
|
||||
AdLibDriver(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer) {
|
||||
AdLibDriver(Audio::Mixer *mixer) {
|
||||
for (uint i = 0; i < 16; ++i)
|
||||
_channels[i].init(this, i);
|
||||
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
int open();
|
||||
@ -282,12 +284,9 @@ public:
|
||||
void send(uint32 b);
|
||||
MidiChannel *allocateChannel();
|
||||
MidiChannel *getPercussionChannel() { return &_channels[9]; }
|
||||
bool isOpen() const { return _isOpen; }
|
||||
uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
|
||||
|
||||
bool isStereo() const { return false; }
|
||||
int getRate() const { return _mixer->getOutputRate(); }
|
||||
int readBuffer(int16 *data, const int numSamples);
|
||||
|
||||
void generateSamples(int16 *buf, int len) {}
|
||||
virtual void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
|
||||
_adlibTimerProc = timerProc;
|
||||
_adlibTimerParam = timerParam;
|
||||
@ -331,6 +330,7 @@ private:
|
||||
|
||||
Common::TimerManager::TimerProc _adlibTimerProc;
|
||||
void *_adlibTimerParam;
|
||||
bool _isOpen;
|
||||
};
|
||||
|
||||
MidiDriver *createAdLibDriver() {
|
||||
@ -359,7 +359,7 @@ int AdLibDriver::open() {
|
||||
if (_isOpen)
|
||||
return MERR_ALREADY_OPEN;
|
||||
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
|
||||
_opl = OPL::Config::create();
|
||||
_opl->init();
|
||||
@ -376,7 +376,6 @@ int AdLibDriver::open() {
|
||||
initVoices();
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, AdLibDriver>(this, &AdLibDriver::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -385,7 +384,6 @@ void AdLibDriver::close() {
|
||||
return;
|
||||
|
||||
_isOpen = false;
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
|
||||
delete _opl;
|
||||
}
|
||||
@ -789,10 +787,6 @@ MidiChannel *AdLibDriver::allocateChannel() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int AdLibDriver::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void AdLibDriver::onTimer() {
|
||||
if (_adlibTimerProc)
|
||||
(*_adlibTimerProc)(_adlibTimerParam);
|
||||
|
@ -28,7 +28,7 @@
|
||||
namespace Queen {
|
||||
|
||||
int AdLibMidiDriver::open() {
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
_opl = OPL::Config::create();
|
||||
if (!_opl || !_opl->init())
|
||||
error("Failed to create OPL");
|
||||
@ -41,12 +41,10 @@ int AdLibMidiDriver::open() {
|
||||
}
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, AdLibMidiDriver>(this, &AdLibMidiDriver::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AdLibMidiDriver::close() {
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
delete _opl;
|
||||
}
|
||||
|
||||
@ -110,14 +108,6 @@ 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) {
|
||||
// Dummy implementation
|
||||
}
|
||||
|
||||
int AdLibMidiDriver::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void AdLibMidiDriver::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
|
||||
_adlibTimerProc = timerProc;
|
||||
_adlibTimerParam = timerParam;
|
||||
|
@ -22,14 +22,17 @@
|
||||
|
||||
#include "audio/fmopl.h"
|
||||
#include "audio/mididrv.h"
|
||||
#include "audio/softsynth/emumidi.h"
|
||||
|
||||
namespace Queen {
|
||||
|
||||
class AdLibMidiDriver : public MidiDriver_Emulated {
|
||||
class AdLibMidiDriver : public MidiDriver {
|
||||
public:
|
||||
|
||||
AdLibMidiDriver(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer) { _adlibWaveformSelect = 0; }
|
||||
AdLibMidiDriver() {
|
||||
_adlibWaveformSelect = 0;
|
||||
_isOpen = false;
|
||||
}
|
||||
|
||||
~AdLibMidiDriver() {}
|
||||
|
||||
// MidiDriver
|
||||
@ -40,14 +43,8 @@ public:
|
||||
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);
|
||||
bool isOpen() const { return _isOpen; }
|
||||
uint32 getBaseTempo() { return 1000000 / OPL::OPL::kDefaultCallbackFrequency; }
|
||||
|
||||
void setVolume(uint32 volume);
|
||||
|
||||
@ -74,8 +71,8 @@ private:
|
||||
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 adlibSetChannelVolume(int channel, uint8 volume);
|
||||
void adlibSetupChannelHelper(int channel);
|
||||
void adlibSetChannel0x40(int channel);
|
||||
void adlibSetChannel0xC0(int channel);
|
||||
@ -106,6 +103,7 @@ private:
|
||||
uint16 _adlibMetaSequenceData[28];
|
||||
uint8 _adlibChannelsVolumeTable[11];
|
||||
|
||||
bool _isOpen;
|
||||
Common::TimerManager::TimerProc _adlibTimerProc;
|
||||
void *_adlibTimerParam;
|
||||
|
||||
|
@ -68,7 +68,7 @@ MidiMusic::MidiMusic(QueenEngine *vm)
|
||||
// if (READ_LE_UINT16(_musicData + 2) != infoOffset) {
|
||||
// defaultAdLibVolume = _musicData[infoOffset];
|
||||
// }
|
||||
_driver = new AdLibMidiDriver(g_system->getMixer());
|
||||
_driver = new AdLibMidiDriver();
|
||||
} else {
|
||||
_driver = MidiDriver::createMidi(dev);
|
||||
if (_nativeMT32) {
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "audio/fmopl.h"
|
||||
#include "audio/softsynth/emumidi.h"
|
||||
#include "audio/mididrv.h"
|
||||
|
||||
#include "sci/resource.h"
|
||||
#include "sci/sound/drivers/mididriver.h"
|
||||
@ -43,30 +43,27 @@ namespace Sci {
|
||||
// FIXME: We don't seem to be sending the polyphony init data, so disable this for now
|
||||
#define ADLIB_DISABLE_VOICE_MAPPING
|
||||
|
||||
class MidiDriver_AdLib : public MidiDriver_Emulated {
|
||||
class MidiDriver_AdLib : public MidiDriver {
|
||||
public:
|
||||
enum {
|
||||
kVoices = 9,
|
||||
kRhythmKeys = 62
|
||||
};
|
||||
|
||||
MidiDriver_AdLib(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15), _rhythmKeyMap(0), _opl(0) { }
|
||||
MidiDriver_AdLib(Audio::Mixer *mixer) :_playSwitch(true), _masterVolume(15), _rhythmKeyMap(0), _opl(0), _isOpen(false) { }
|
||||
virtual ~MidiDriver_AdLib() { }
|
||||
|
||||
// MidiDriver
|
||||
int open() { return -1; } // Dummy implementation (use openAdLib)
|
||||
int openAdLib(bool isSCI0);
|
||||
void close();
|
||||
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
|
||||
int readBuffer(int16 *data, const int numSamples);
|
||||
bool isStereo() const { return _stereo; }
|
||||
int getRate() const { return _mixer->getOutputRate(); }
|
||||
|
||||
// MidiDriver_Emulated
|
||||
void generateSamples(int16 *buf, int len);
|
||||
// MidiDriver
|
||||
void setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc);
|
||||
|
||||
void onTimer();
|
||||
@ -137,6 +134,7 @@ private:
|
||||
bool _stereo;
|
||||
bool _isSCI0;
|
||||
OPL::OPL *_opl;
|
||||
bool _isOpen;
|
||||
bool _playSwitch;
|
||||
int _masterVolume;
|
||||
Channel _channels[MIDI_CHANNELS];
|
||||
@ -227,7 +225,7 @@ int MidiDriver_AdLib::openAdLib(bool isSCI0) {
|
||||
debug(3, "ADLIB: Starting driver in %s mode", (isSCI0 ? "SCI0" : "SCI1"));
|
||||
_isSCI0 = isSCI0;
|
||||
|
||||
_opl = OPL::Config::create(isStereo() ? OPL::Config::kDualOpl2 : OPL::Config::kOpl2);
|
||||
_opl = OPL::Config::create(_stereo ? OPL::Config::kDualOpl2 : OPL::Config::kOpl2);
|
||||
|
||||
// Try falling back to mono, thus plain OPL2 emualtor, when no Dual OPL2 is available.
|
||||
if (!_opl && _stereo) {
|
||||
@ -244,17 +242,14 @@ int MidiDriver_AdLib::openAdLib(bool isSCI0) {
|
||||
setRegister(0x08, 0);
|
||||
setRegister(0x01, 0x20);
|
||||
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, MidiDriver_AdLib>(this, &MidiDriver_AdLib::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MidiDriver_AdLib::close() {
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
|
||||
delete _opl;
|
||||
delete[] _rhythmKeyMap;
|
||||
}
|
||||
@ -331,14 +326,6 @@ void MidiDriver_AdLib::send(uint32 b) {
|
||||
}
|
||||
}
|
||||
|
||||
int MidiDriver_AdLib::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void MidiDriver_AdLib::generateSamples(int16 *data, int len) {
|
||||
// Dummy implementation
|
||||
}
|
||||
|
||||
void MidiDriver_AdLib::setTimerCallback(void *timerParam, Common::TimerManager::TimerProc timerProc) {
|
||||
_adlibTimerProc = timerProc;
|
||||
_adlibTimerParam = timerParam;
|
||||
@ -702,7 +689,7 @@ void MidiDriver_AdLib::setVelocityReg(int regOffset, int velocity, int kbScaleLe
|
||||
if (!_playSwitch)
|
||||
velocity = 0;
|
||||
|
||||
if (isStereo()) {
|
||||
if (_stereo) {
|
||||
int velLeft = velocity;
|
||||
int velRight = velocity;
|
||||
|
||||
@ -752,7 +739,7 @@ void MidiDriver_AdLib::setRegister(int reg, int value, int channels) {
|
||||
_opl->write(0x221, value);
|
||||
}
|
||||
|
||||
if (isStereo()) {
|
||||
if (_stereo) {
|
||||
if (channels & kRightChannel) {
|
||||
_opl->write(0x222, reg);
|
||||
_opl->write(0x223, value);
|
||||
|
@ -36,7 +36,7 @@ namespace Scumm {
|
||||
#define AD_CALLBACK_FREQUENCY 472
|
||||
|
||||
Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
|
||||
: _vm(scumm), _mixer(mixer), _rate(mixer->getOutputRate()) {
|
||||
: _vm(scumm), _mixer(mixer) {
|
||||
_opl2 = OPL::Config::create();
|
||||
if (!_opl2->init()) {
|
||||
error("Could not initialize OPL2 emulator");
|
||||
@ -73,12 +73,9 @@ Player_AD::Player_AD(ScummEngine *scumm, Audio::Mixer *mixer)
|
||||
_isSeeking = false;
|
||||
|
||||
_opl2->start(new Common::Functor0Mem<void, Player_AD>(this, &Player_AD::onTimer), AD_CALLBACK_FREQUENCY);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
Player_AD::~Player_AD() {
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
|
||||
stopAllSounds();
|
||||
Common::StackLock lock(_mutex);
|
||||
delete _opl2;
|
||||
@ -250,10 +247,6 @@ void Player_AD::onTimer() {
|
||||
updateSfx();
|
||||
}
|
||||
|
||||
int Player_AD::readBuffer(int16 *buffer, const int numSamples) {
|
||||
return _opl2->readBuffer(buffer, numSamples);
|
||||
}
|
||||
|
||||
void Player_AD::setupVolume() {
|
||||
// Setup the correct volume
|
||||
_musicVolume = CLIP<int>(ConfMan.getInt("music_volume"), 0, Audio::Mixer::kMaxChannelVolume);
|
||||
|
@ -41,7 +41,7 @@ class ScummEngine;
|
||||
/**
|
||||
* Sound output for v3/v4 AdLib data.
|
||||
*/
|
||||
class Player_AD : public MusicEngine, public Audio::AudioStream {
|
||||
class Player_AD : public MusicEngine {
|
||||
public:
|
||||
Player_AD(ScummEngine *scumm, Audio::Mixer *mixer);
|
||||
virtual ~Player_AD();
|
||||
@ -56,12 +56,6 @@ public:
|
||||
|
||||
virtual void saveLoadWithSerializer(Serializer *ser);
|
||||
|
||||
// AudioStream API
|
||||
virtual int readBuffer(int16 *buffer, const int numSamples);
|
||||
virtual bool isStereo() const { return false; }
|
||||
virtual bool endOfData() const { return false; }
|
||||
virtual int getRate() const { return _rate; }
|
||||
|
||||
// Timer callback
|
||||
void onTimer();
|
||||
|
||||
@ -69,8 +63,6 @@ private:
|
||||
ScummEngine *const _vm;
|
||||
Common::Mutex _mutex;
|
||||
Audio::Mixer *const _mixer;
|
||||
const int _rate;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
|
||||
void setupVolume();
|
||||
int _musicVolume;
|
||||
|
@ -216,11 +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),
|
||||
_adlibTimerProc(0), _adlibTimerParam(0) {
|
||||
: _masterVolume(15), _opl(0),
|
||||
_adlibTimerProc(0), _adlibTimerParam(0), _isOpen(false) {
|
||||
memset(_voiceChannelMapping, 0, sizeof(_voiceChannelMapping));
|
||||
}
|
||||
virtual ~MidiDriver_SH_AdLib() { }
|
||||
@ -231,17 +231,12 @@ 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
|
||||
int readBuffer(int16 *data, const int numSamples);
|
||||
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);
|
||||
@ -268,6 +263,8 @@ private:
|
||||
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];
|
||||
|
||||
@ -299,16 +296,16 @@ int MidiDriver_SH_AdLib::open() {
|
||||
|
||||
_opl->init();
|
||||
|
||||
MidiDriver_Emulated::open();
|
||||
_isOpen = true;
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, MidiDriver_SH_AdLib>(this, &MidiDriver_SH_AdLib::onTimer));
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_mixerSoundHandle, this, -1, _mixer->kMaxChannelVolume, 0, DisposeAfterUse::NO);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MidiDriver_SH_AdLib::close() {
|
||||
_mixer->stopHandle(_mixerSoundHandle);
|
||||
// Stop the OPL timer
|
||||
_opl->stop();
|
||||
|
||||
delete _opl;
|
||||
}
|
||||
@ -427,14 +424,6 @@ void MidiDriver_SH_AdLib::send(uint32 b) {
|
||||
}
|
||||
}
|
||||
|
||||
void MidiDriver_SH_AdLib::generateSamples(int16 *data, int len) {
|
||||
// Dummy implementation until we no longer inherit from MidiDriver_Emulated
|
||||
}
|
||||
|
||||
int MidiDriver_SH_AdLib::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void MidiDriver_SH_AdLib::noteOn(byte MIDIchannel, byte note, byte velocity) {
|
||||
int16 oldestInUseChannel = -1;
|
||||
uint16 oldestInUseTimer = 0;
|
||||
|
@ -33,25 +33,18 @@ namespace Sky {
|
||||
|
||||
AdLibMusic::AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk) : MusicBase(pMixer, pDisk) {
|
||||
_driverFileBase = 60202;
|
||||
_sampleRate = pMixer->getOutputRate();
|
||||
|
||||
_opl = OPL::Config::create();
|
||||
if (!_opl || !_opl->init())
|
||||
error("Failed to create OPL");
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, AdLibMusic>(this, &AdLibMusic::onTimer), 50);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
AdLibMusic::~AdLibMusic() {
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
delete _opl;
|
||||
}
|
||||
|
||||
int AdLibMusic::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void AdLibMusic::onTimer() {
|
||||
if (_musicData != NULL)
|
||||
pollMusic();
|
||||
@ -97,16 +90,4 @@ void AdLibMusic::setVolume(uint16 param) {
|
||||
_channels[cnt]->updateVolume(_musicVolume);
|
||||
}
|
||||
|
||||
bool AdLibMusic::isStereo() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdLibMusic::endOfData() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
int AdLibMusic::getRate() const {
|
||||
return _sampleRate;
|
||||
}
|
||||
|
||||
} // End of namespace Sky
|
||||
|
@ -32,21 +32,16 @@ class OPL;
|
||||
|
||||
namespace Sky {
|
||||
|
||||
class AdLibMusic : public Audio::AudioStream, public MusicBase {
|
||||
class AdLibMusic : public MusicBase {
|
||||
public:
|
||||
AdLibMusic(Audio::Mixer *pMixer, Disk *pDisk);
|
||||
~AdLibMusic();
|
||||
|
||||
// AudioStream API
|
||||
int readBuffer(int16 *buffer, const int numSamples);
|
||||
bool isStereo() const;
|
||||
bool endOfData() const;
|
||||
int getRate() const;
|
||||
virtual void setVolume(uint16 param);
|
||||
|
||||
private:
|
||||
OPL::OPL *_opl;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
uint8 *_initSequence;
|
||||
uint32 _sampleRate;
|
||||
virtual void setupPointers();
|
||||
|
@ -2743,7 +2743,6 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
|
||||
_groupData._pData = &adlib_group_data[0];
|
||||
|
||||
_mixer = g_vm->_mixer;
|
||||
_sampleRate = _mixer->getOutputRate();
|
||||
_opl = OPL::Config::create();
|
||||
assert(_opl);
|
||||
_opl->init();
|
||||
@ -2767,12 +2766,10 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
|
||||
}
|
||||
|
||||
_opl->start(new Common::Functor0Mem<void, AdlibSoundDriver>(this, &AdlibSoundDriver::onTimer), CALLBACKS_PER_SECOND);
|
||||
_mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
|
||||
}
|
||||
|
||||
AdlibSoundDriver::~AdlibSoundDriver() {
|
||||
DEALLOCATE(_patchData);
|
||||
_mixer->stopHandle(_soundHandle);
|
||||
delete _opl;
|
||||
}
|
||||
|
||||
@ -3015,10 +3012,6 @@ void AdlibSoundDriver::setFrequency(int channel) {
|
||||
((dataWord >> 8) & 3) | (var2 << 2));
|
||||
}
|
||||
|
||||
int AdlibSoundDriver::readBuffer(int16 *data, const int numSamples) {
|
||||
return _opl->readBuffer(data, numSamples);
|
||||
}
|
||||
|
||||
void AdlibSoundDriver::onTimer() {
|
||||
Common::StackLock slock1(SoundManager::sfManager()._serverDisabledMutex);
|
||||
Common::StackLock slock2(SoundManager::sfManager()._serverSuspendedMutex);
|
||||
|
@ -449,13 +449,11 @@ public:
|
||||
|
||||
#define ADLIB_CHANNEL_COUNT 9
|
||||
|
||||
class AdlibSoundDriver: public SoundDriver, Audio::AudioStream {
|
||||
class AdlibSoundDriver: public SoundDriver {
|
||||
private:
|
||||
GroupData _groupData;
|
||||
Audio::Mixer *_mixer;
|
||||
OPL::OPL *_opl;
|
||||
Audio::SoundHandle _soundHandle;
|
||||
int _sampleRate;
|
||||
byte _portContents[256];
|
||||
const byte *_patchData;
|
||||
int _masterVolume;
|
||||
@ -494,12 +492,6 @@ public:
|
||||
virtual void proc38(int channel, int cmd, int value);
|
||||
virtual void setPitch(int channel, int pitchBlend);
|
||||
|
||||
// AudioStream interface
|
||||
virtual int readBuffer(int16 *data, const int numSamples);
|
||||
virtual bool isStereo() const { return false; }
|
||||
virtual bool endOfData() const { return false; }
|
||||
virtual int getRate() const { return _sampleRate; }
|
||||
|
||||
private:
|
||||
void onTimer();
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user