renamed SoundMixer::hasActiveChannel->hasActiveSFXChannel, and fixed the regression in it caused by removing _beginSlots (I hope); added isActiveChannel method used by scumm/sound.cpp (this allowed me to move the Channel class from mixer.h into mixer.cpp); replaced Channel::soundFinished method by isActive

svn-id: r8597
This commit is contained in:
Max Horn 2003-06-22 01:55:53 +00:00
parent 573a1e3e99
commit 4ad5a183ce
3 changed files with 59 additions and 35 deletions

View file

@ -958,7 +958,7 @@ void Sound::stopSfxSound() {
} }
bool Sound::isSfxFinished() { bool Sound::isSfxFinished() {
return !_scumm->_mixer->hasActiveChannel(); return !_scumm->_mixer->hasActiveSFXChannel();
} }
uint32 Sound::decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo = false) { uint32 Sound::decode12BitsSample(byte *src, byte **dst, uint32 size, bool stereo = false) {
@ -1577,7 +1577,7 @@ int Sound::updateMP3CD() {
return -1; return -1;
} }
if (_scumm->_mixer->_channels[_dig_cd_index]->soundFinished()) { if (!_scumm->_mixer->isActiveChannel(_dig_cd_index)) {
if (_dig_cd_num_loops == -1 || --_dig_cd_num_loops > 0) if (_dig_cd_num_loops == -1 || --_dig_cd_num_loops > 0)
playMP3CDTrack(_dig_cd_track, _dig_cd_num_loops, _dig_cd_start, _dig_cd_delay); playMP3CDTrack(_dig_cd_track, _dig_cd_num_loops, _dig_cd_start, _dig_cd_delay);
else else

View file

@ -26,6 +26,22 @@
#include "common/file.h" #include "common/file.h"
class Channel {
protected:
SoundMixer *_mixer;
public:
bool _toBeDestroyed;
int _id;
Channel() : _mixer(0), _toBeDestroyed(false), _id(-1) {}
virtual ~Channel() {}
virtual void mix(int16 *data, uint len) = 0;
void destroy() {
_toBeDestroyed = true;
}
virtual bool isActive();
virtual bool isMusicChannel() = 0;
};
class ChannelRaw : public Channel { class ChannelRaw : public Channel {
byte *_ptr; byte *_ptr;
uint32 _pos; uint32 _pos;
@ -42,6 +58,9 @@ public:
~ChannelRaw(); ~ChannelRaw();
void mix(int16 *data, uint len); void mix(int16 *data, uint len);
bool isMusicChannel() {
return false; // TODO: IS this correct? Or does any Scumm game us this for music?
}
}; };
class ChannelStream : public Channel { class ChannelStream : public Channel {
@ -61,6 +80,9 @@ public:
void mix(int16 *data, uint len); void mix(int16 *data, uint len);
void append(void *sound, uint32 size); void append(void *sound, uint32 size);
bool isMusicChannel() {
return true;
}
}; };
#ifdef USE_MAD #ifdef USE_MAD
@ -81,6 +103,9 @@ public:
~ChannelMP3(); ~ChannelMP3();
void mix(int16 *data, uint len); void mix(int16 *data, uint len);
bool isMusicChannel() {
return false;
}
}; };
class ChannelMP3CDMusic : public Channel { class ChannelMP3CDMusic : public Channel {
@ -101,7 +126,10 @@ public:
~ChannelMP3CDMusic(); ~ChannelMP3CDMusic();
void mix(int16 *data, uint len); void mix(int16 *data, uint len);
bool soundFinished(); bool isActive();
bool isMusicChannel() {
return true;
}
}; };
#endif #endif
@ -116,7 +144,10 @@ public:
ChannelVorbis(SoundMixer *mixer, OggVorbis_File *ov_file, int duration, bool is_cd_track); ChannelVorbis(SoundMixer *mixer, OggVorbis_File *ov_file, int duration, bool is_cd_track);
void mix(int16 *data, uint len); void mix(int16 *data, uint len);
bool soundFinished(); bool isActive();
bool isMusicChannel() {
return _is_cd_track;
}
}; };
#endif #endif
@ -276,13 +307,23 @@ void SoundMixer::pause(bool paused) {
_paused = paused; _paused = paused;
} }
bool SoundMixer::hasActiveChannel() { bool SoundMixer::hasActiveSFXChannel() {
// FIXME/TODO: We need to distinguish between SFX and music channels
// (and maybe also voice) here to work properly in iMuseDigital
// games. In the past that was achieve using the _beginSlots hack.
// Since we don't have that anymore, it's not that simple anymore.
for (int i = 0; i != NUM_CHANNELS; i++) for (int i = 0; i != NUM_CHANNELS; i++)
if (_channels[i]) if (_channels[i] && !_channels[i]->isMusicChannel())
return true; return true;
return false; return false;
} }
bool SoundMixer::isActiveChannel(int index) {
if (_channels[index])
return _channels[index]->isActive();
return false;
}
void SoundMixer::setupPremix(void *param, PremixProc *proc) { void SoundMixer::setupPremix(void *param, PremixProc *proc) {
_premixParam = param; _premixParam = param;
_premixProc = proc; _premixProc = proc;
@ -596,9 +637,9 @@ static int16 mixer_element_size[] = {
4, 4 4, 4
}; };
bool Channel::soundFinished() { bool Channel::isActive() {
warning("sound_finished should never be called on a non-MP3 mixer "); error("isActive should never be called on a non-MP3 mixer ");
return false; return true;
} }
/* RAW mixer */ /* RAW mixer */
@ -979,8 +1020,8 @@ void ChannelMP3CDMusic::mix(int16 *data, uint len) {
} }
} }
bool ChannelMP3CDMusic::soundFinished() { bool ChannelMP3CDMusic::isActive() {
return mad_timer_compare(_duration, mad_timer_zero) <= 0; return mad_timer_compare(_duration, mad_timer_zero) > 0;
} }
#endif #endif
@ -1061,8 +1102,8 @@ void ChannelVorbis::mix(int16 *data, uint len) {
destroy(); destroy();
} }
bool ChannelVorbis::soundFinished() { bool ChannelVorbis::isActive() {
return _eof_flag || (_end_pos > 0 && ov_pcm_tell(_ov_file) >= _end_pos); return !_eof_flag && (_end_pos <= 0 && ov_pcm_tell(_ov_file) >= _end_pos);
} }
#endif #endif

View file

@ -41,26 +41,6 @@ typedef uint32 PlayingSoundHandle;
class Channel; class Channel;
class File; class File;
class SoundMixer;
// TODO: class Channel should really be declared non-public, inside mixer.cpp
// However, right now Sound::updateMP3CD directly calls soundFinished. That
// should be changed, by adding proper API abstraction to SoundMixer for
// MP3/Vorbis "CD" playback.
class Channel {
protected:
SoundMixer *_mixer;
public:
bool _toBeDestroyed;
int _id;
Channel() : _mixer(0), _toBeDestroyed(false), _id(-1) {}
virtual ~Channel() {}
virtual void mix(int16 *data, uint len) = 0;
void destroy() {
_toBeDestroyed = true;
}
virtual bool soundFinished();
};
class SoundMixer { class SoundMixer {
public: public:
@ -133,8 +113,11 @@ public:
/** append to existing sound */ /** append to existing sound */
int append(int index, void * sound, uint32 size); int append(int index, void * sound, uint32 size);
/** is any channel active? */ /** Check whether any SFX channel is active.*/
bool hasActiveChannel(); bool hasActiveSFXChannel();
/** Check whether the specified channel si active. */
bool isActiveChannel(int index);
/** bind to the OSystem object => mixer will be /** bind to the OSystem object => mixer will be
* invoked automatically when samples need * invoked automatically when samples need