aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2011-06-20 19:42:13 +1000
committerPaul Gilbert2011-06-20 19:44:57 +1000
commit123f2416d8074a50e2c42c83caaf94961d4c6d36 (patch)
tree4a06cb06664a2e86d9cfaadb28b0d9f18144c1dd
parentdae19afbfb0ba288755bd83c9bee5e0c48620c6a (diff)
downloadscummvm-rg350-123f2416d8074a50e2c42c83caaf94961d4c6d36.tar.gz
scummvm-rg350-123f2416d8074a50e2c42c83caaf94961d4c6d36.tar.bz2
scummvm-rg350-123f2416d8074a50e2c42c83caaf94961d4c6d36.zip
TSAGE: Initial implementation of AudioStream interface for sound driver
-rw-r--r--engines/tsage/events.cpp6
-rw-r--r--engines/tsage/sound.cpp51
-rw-r--r--engines/tsage/sound.h22
3 files changed, 72 insertions, 7 deletions
diff --git a/engines/tsage/events.cpp b/engines/tsage/events.cpp
index 94c074a50b..a24f65421b 100644
--- a/engines/tsage/events.cpp
+++ b/engines/tsage/events.cpp
@@ -48,9 +48,8 @@ bool EventsClass::pollEvent() {
_priorFrameTime = milli;
++_frameNumber;
- // Update screen and allow the sound manager to process pending sounds
+ // Update screen
g_system->updateScreen();
- SoundManager::_sfSoundServer();
}
if (!g_system->getEventManager()->pollEvent(_event)) return false;
@@ -299,9 +298,6 @@ void EventsClass::delay(int numFrames) {
++_frameNumber;
_priorFrameTime = g_system->getMillis();
-
- // Allow pending sounds to be processed
- SoundManager::_sfSoundServer();
}
g_system->updateScreen();
diff --git a/engines/tsage/sound.cpp b/engines/tsage/sound.cpp
index 0c0d93be03..24c64bda3c 100644
--- a/engines/tsage/sound.cpp
+++ b/engines/tsage/sound.cpp
@@ -51,6 +51,8 @@ SoundManager::SoundManager() {
_needToRethink = false;
_soTimeIndexFlag = false;
+ _updateTicksCounter = 0;
+ _eventsDelay = GAME_FRAME_TIME;
}
SoundManager::~SoundManager() {
@@ -114,6 +116,14 @@ void SoundManager::syncSounds() {
this->setMasterVol(musicVolume / 2);
}
+void SoundManager::update() {
+ ++_updateTicksCounter;
+ if (_updateTicksCounter > _eventsDelay) {
+ _sfSoundServer();
+ _updateTicksCounter = 0;
+ }
+}
+
Common::List<SoundDriverEntry> &SoundManager::buildDriverList(bool detectFlag) {
assert(__sndmgrReady);
_availableDrivers.clear();
@@ -482,6 +492,10 @@ void SoundManager::_sfUpdateVoiceStructs2() {
}
}
+void SoundManager::_sfUpdateCallback(void *ref) {
+ ((SoundManager *)ref)->update();
+}
+
/*--------------------------------------------------------------------------*/
void SoundManager::saveNotifier(bool postFlag) {
@@ -1293,7 +1307,8 @@ void SoundManager::_sfExtractGroupMask() {
bool SoundManager::_sfInstallDriver(SoundDriver *driver) {
if (!driver->open())
return false;
-
+
+ driver->setUpdateCallback(_sfUpdateCallback, (void *)&sfManager());
sfManager()._installedDrivers.push_back(driver);
driver->_groupOffset = driver->getGroupData();
driver->_groupMask = READ_LE_UINT32(driver->_groupOffset);
@@ -2376,6 +2391,8 @@ const int v440D4[48] = {
};
AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
+ _upCb = NULL;
+ _upRef = NULL;
_minVersion = 0x102;
_maxVersion = 0x10A;
_masterVolume = 0;
@@ -2388,6 +2405,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
_mixer = _vm->_mixer;
_sampleRate = _mixer->getOutputRate();
_opl = makeAdLibOPL(_sampleRate);
+ _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
Common::set_to(_channelVoiced, _channelVoiced + ADLIB_CHANNEL_COUNT, false);
memset(_channelVolume, 0, ADLIB_CHANNEL_COUNT * sizeof(int));
@@ -2404,6 +2422,7 @@ AdlibSoundDriver::AdlibSoundDriver(): SoundDriver() {
AdlibSoundDriver::~AdlibSoundDriver() {
DEALLOCATE(_patchData);
+ _mixer->stopHandle(_soundHandle);
OPLDestroy(_opl);
}
@@ -2640,4 +2659,34 @@ void AdlibSoundDriver::setFrequency(int channel) {
((dataWord >> 8) & 3) | (var2 << 2));
}
+int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) {
+ update(buffer, numSamples);
+ return numSamples;
+}
+
+void AdlibSoundDriver::update(int16 *buf, int len) {
+ static int samplesLeft = 0;
+ while (len != 0) {
+ int count = samplesLeft;
+ if (count > len) {
+ count = len;
+ }
+ samplesLeft -= count;
+ len -= count;
+ YM3812UpdateOne(_opl, buf, count);
+ if (samplesLeft == 0) {
+ if (_upCb) {
+ (*_upCb)(_upRef);
+ }
+ samplesLeft = _sampleRate / 50;
+ }
+ buf += count;
+ }
+}
+
+void AdlibSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) {
+ _upCb = upCb;
+ _upRef = ref;
+}
+
} // End of namespace tSage
diff --git a/engines/tsage/sound.h b/engines/tsage/sound.h
index 4cda2cd1d9..ed93d33443 100644
--- a/engines/tsage/sound.h
+++ b/engines/tsage/sound.h
@@ -72,6 +72,10 @@ public:
uint32 _groupMask;
const GroupData *_groupOffset;
int _driverResID;
+
+ typedef void (*UpdateCallback)(void *);
+ UpdateCallback _upCb;
+ void *_upRef;
public:
SoundDriver();
virtual ~SoundDriver() {};
@@ -101,6 +105,8 @@ public:
virtual void proc38(int channel, int cmd, int value) {} // Method #19
virtual void setPitch(int channel, int pitchBlend) {} // Method #20
virtual void proc42(int channel, int v0, int v1) {} // Method #21
+
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref) {}
};
struct VoiceStructEntryType0 {
@@ -171,6 +177,8 @@ public:
Common::List<Sound *> _soundList;
Common::List<SoundDriverEntry> _availableDrivers;
bool _needToRethink;
+ int _updateTicksCounter;
+ int _eventsDelay;
// Misc flags
bool _soTimeIndexFlag;
public:
@@ -181,6 +189,7 @@ public:
virtual void listenerSynchronize(Serializer &s);
virtual void postInit();
void syncSounds();
+ void update();
static void saveNotifier(bool postFlag);
void saveNotifierProc(bool postFlag);
@@ -243,6 +252,7 @@ public:
static void _sfProcessFading();
static void _sfUpdateVoiceStructs();
static void _sfUpdateVoiceStructs2();
+ static void _sfUpdateCallback(void *ref);
};
class Sound: public EventHandler {
@@ -387,11 +397,12 @@ public:
#define ADLIB_CHANNEL_COUNT 9
-class AdlibSoundDriver: public SoundDriver {
+class AdlibSoundDriver: public SoundDriver, Audio::AudioStream {
private:
GroupData _groupData;
Audio::Mixer *_mixer;
FM_OPL *_opl;
+ Audio::SoundHandle _soundHandle;
int _sampleRate;
byte _portContents[256];
const byte *_patchData;
@@ -428,6 +439,15 @@ public:
virtual void updateVoice(int channel);
virtual void proc38(int channel, int cmd, int value);
virtual void setPitch(int channel, int pitchBlend);
+ virtual void setUpdateCallback(UpdateCallback upCb, void *ref);
+
+ // 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 update(int16 *buf, int len);
};
} // End of namespace tSage