mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-17 23:27:37 +00:00
Moved the audio CD handling code inside the AudioPlayer class. Some cleanup
svn-id: r45656
This commit is contained in:
parent
2dbf6662fc
commit
7d00c4a7f1
@ -30,8 +30,6 @@
|
||||
#include "sci/engine/kernel.h"
|
||||
#include "sci/engine/vm.h" // for Object
|
||||
|
||||
#include "sound/audiocd.h"
|
||||
#include "sound/audiostream.h"
|
||||
#include "sound/mixer.h"
|
||||
|
||||
namespace Sci {
|
||||
@ -1028,60 +1026,17 @@ reg_t kDoCdAudio(EngineState *s, int argc, reg_t *argv) {
|
||||
switch (argv[0].toUint16()) {
|
||||
case kSciAudioWPlay:
|
||||
case kSciAudioPlay: {
|
||||
if (getSciVersion() == SCI_VERSION_1_1) {
|
||||
// King's Quest VI CD Audio format
|
||||
if (argc < 2)
|
||||
return NULL_REG;
|
||||
if (argc < 2)
|
||||
return NULL_REG;
|
||||
|
||||
uint16 track = argv[1].toUint16() - 1;
|
||||
uint32 startFrame = 0;
|
||||
uint32 totalFrames = 0;
|
||||
uint16 track = argv[1].toUint16() - 1;
|
||||
uint32 startFrame = (argc > 2) ? argv[2].toUint16() * 75 : 0;
|
||||
uint32 totalFrames = (argc > 3) ? argv[3].toUint16() * 75 : 0;
|
||||
|
||||
if (argc > 2)
|
||||
startFrame = argv[2].toUint16() * 75;
|
||||
|
||||
if (argc > 3)
|
||||
totalFrames = argv[3].toUint16() * 75;
|
||||
|
||||
AudioCD.play(track, 1, startFrame, totalFrames);
|
||||
return make_reg(0, 1);
|
||||
} else {
|
||||
// Jones in the Fast Lane CD Audio format
|
||||
if (argc != 2)
|
||||
error("kDoCdAudio(%d) called with %d args", argv[0].toUint16(), argc);
|
||||
|
||||
AudioCD.stop();
|
||||
|
||||
Common::File audioMap;
|
||||
if(!audioMap.open("cdaudio.map"))
|
||||
error("Could not open cdaudio.map");
|
||||
|
||||
uint16 sample = argv[1].toUint16();
|
||||
uint32 length = 0;
|
||||
|
||||
while (audioMap.pos() < audioMap.size()) {
|
||||
uint16 res = audioMap.readUint16LE();
|
||||
uint32 startFrame = audioMap.readUint16LE();
|
||||
startFrame += audioMap.readByte() << 16;
|
||||
audioMap.readByte(); // Unknown, always 0x20
|
||||
length = audioMap.readUint16LE();
|
||||
length += audioMap.readByte() << 16;
|
||||
audioMap.readByte(); // Unknown, always 0x00
|
||||
|
||||
if (res == sample) {
|
||||
AudioCD.play(1, 1, startFrame, length);
|
||||
s->_audioCdStart = g_system->getMillis();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
audioMap.close();
|
||||
|
||||
return make_reg(0, length * 60 / 75); // return sample length in ticks
|
||||
}
|
||||
return make_reg(0, s->_audio->audioCdPlay(track, startFrame, totalFrames));
|
||||
}
|
||||
case kSciAudioStop:
|
||||
AudioCD.stop();
|
||||
s->_audio->audioCdStop();
|
||||
|
||||
if (getSciVersion() == SCI_VERSION_1_1)
|
||||
return make_reg(0, 1);
|
||||
@ -1093,15 +1048,10 @@ reg_t kDoCdAudio(EngineState *s, int argc, reg_t *argv) {
|
||||
case kSciAudioResume:
|
||||
// This seems to be hacked up to update the CD instead of resuming
|
||||
// audio like kDoAudio does.
|
||||
AudioCD.updateCD();
|
||||
s->_audio->audioCdUpdate();
|
||||
break;
|
||||
case kSciAudioPosition:
|
||||
// Return -1 if the sample is done playing. Converting to frames to compare.
|
||||
if (((g_system->getMillis() - s->_audioCdStart) * 75 / 1000) >= (uint32)AudioCD.getStatus().duration)
|
||||
return SIGNAL_REG;
|
||||
|
||||
// Return the position otherwise (in ticks).
|
||||
return make_reg(0, (g_system->getMillis() - s->_audioCdStart) * 60 / 1000);
|
||||
return make_reg(0, s->_audio->audioCdPosition());
|
||||
case kSciAudioRate: // No need to set the audio rate
|
||||
case kSciAudioVolume: // The speech setting isn't used by CD Audio
|
||||
case kSciAudioLanguage: // No need to set the language
|
||||
|
@ -110,7 +110,6 @@ EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc,
|
||||
_gfxFunctionsType = SCI_VERSION_AUTODETECT;
|
||||
_moveCountType = kMoveCountUninitialized;
|
||||
|
||||
_audioCdStart = 0;
|
||||
_usesCdTrack = Common::File::exists("cdaudio.map");
|
||||
}
|
||||
|
||||
|
@ -286,8 +286,7 @@ public:
|
||||
EngineState *successor; /**< Successor of this state: Used for restoring */
|
||||
|
||||
Common::String getLanguageString(const char *str, kLanguage lang) const;
|
||||
|
||||
uint32 _audioCdStart;
|
||||
|
||||
private:
|
||||
SciVersion _doSoundType, _setCursorType, _lofsType, _gfxFunctionsType;
|
||||
MoveCountType _moveCountType;
|
||||
|
@ -31,17 +31,26 @@
|
||||
#include "common/system.h"
|
||||
|
||||
#include "sound/audiostream.h"
|
||||
#include "sound/audiocd.h"
|
||||
#include "sound/mixer.h"
|
||||
|
||||
namespace Sci {
|
||||
|
||||
AudioPlayer::AudioPlayer(ResourceManager *resMan) : _resMan(resMan), _audioRate(11025),
|
||||
_syncResource(NULL), _syncOffset(0) {
|
||||
_syncResource(NULL), _syncOffset(0), _audioCdStart(0) {
|
||||
|
||||
_mixer = g_system->getMixer();
|
||||
}
|
||||
|
||||
AudioPlayer::~AudioPlayer() {
|
||||
stopAllAudio();
|
||||
}
|
||||
|
||||
void AudioPlayer::stopAllAudio() {
|
||||
stopSoundSync();
|
||||
stopAudio();
|
||||
if (_audioCdStart > 0)
|
||||
audioCdStop();
|
||||
}
|
||||
|
||||
int AudioPlayer::startAudio(uint16 module, uint32 number) {
|
||||
@ -49,16 +58,28 @@ int AudioPlayer::startAudio(uint16 module, uint32 number) {
|
||||
Audio::AudioStream *audioStream = getAudioStream(number, module, &sampleLen);
|
||||
|
||||
if (audioStream) {
|
||||
g_system->getMixer()->playInputStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream);
|
||||
_mixer->playInputStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream);
|
||||
return sampleLen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AudioPlayer::stopAudio() {
|
||||
_mixer->stopHandle(_audioHandle);
|
||||
}
|
||||
|
||||
void AudioPlayer::pauseAudio() {
|
||||
_mixer->pauseHandle(_audioHandle, true);
|
||||
}
|
||||
|
||||
void AudioPlayer::resumeAudio() {
|
||||
_mixer->pauseHandle(_audioHandle, false);
|
||||
}
|
||||
|
||||
int AudioPlayer::getAudioPosition() {
|
||||
if (g_system->getMixer()->isSoundHandleActive(_audioHandle))
|
||||
return g_system->getMixer()->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks
|
||||
if (_mixer->isSoundHandleActive(_audioHandle))
|
||||
return _mixer->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks
|
||||
else
|
||||
return -1; // Sound finished
|
||||
}
|
||||
@ -261,4 +282,60 @@ void AudioPlayer::stopSoundSync() {
|
||||
}
|
||||
}
|
||||
|
||||
int AudioPlayer::audioCdPlay(int track, int start, int duration) {
|
||||
if (getSciVersion() == SCI_VERSION_1_1) {
|
||||
// King's Quest VI CD Audio format
|
||||
_audioCdStart = g_system->getMillis();
|
||||
AudioCD.play(track, 1, start, duration);
|
||||
return 1;
|
||||
} else {
|
||||
// Jones in the Fast Lane CD Audio format
|
||||
uint32 length = 0;
|
||||
|
||||
audioCdStop();
|
||||
|
||||
Common::File audioMap;
|
||||
if(!audioMap.open("cdaudio.map"))
|
||||
error("Could not open cdaudio.map");
|
||||
|
||||
while (audioMap.pos() < audioMap.size()) {
|
||||
uint16 res = audioMap.readUint16LE();
|
||||
uint32 startFrame = audioMap.readUint16LE();
|
||||
startFrame += audioMap.readByte() << 16;
|
||||
audioMap.readByte(); // Unknown, always 0x20
|
||||
length = audioMap.readUint16LE();
|
||||
length += audioMap.readByte() << 16;
|
||||
audioMap.readByte(); // Unknown, always 0x00
|
||||
|
||||
if (res == track) {
|
||||
AudioCD.play(1, 1, startFrame, length);
|
||||
_audioCdStart = g_system->getMillis();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
audioMap.close();
|
||||
|
||||
return length * 60 / 75; // return sample length in ticks
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::audioCdStop() {
|
||||
_audioCdStart = 0;
|
||||
AudioCD.stop();
|
||||
}
|
||||
|
||||
void AudioPlayer::audioCdUpdate() {
|
||||
AudioCD.updateCD();
|
||||
}
|
||||
|
||||
int AudioPlayer::audioCdPosition() {
|
||||
// Return -1 if the sample is done playing. Converting to frames to compare.
|
||||
if (((g_system->getMillis() - _audioCdStart) * 75 / 1000) >= (uint32)AudioCD.getStatus().duration)
|
||||
return -1;
|
||||
|
||||
// Return the position otherwise (in ticks).
|
||||
return (g_system->getMillis() - _audioCdStart) * 60 / 1000;
|
||||
}
|
||||
|
||||
} // End of namespace Sci
|
||||
|
@ -41,21 +41,31 @@ public:
|
||||
Audio::SoundHandle* getAudioHandle() { return &_audioHandle; }
|
||||
int getAudioPosition();
|
||||
int startAudio(uint16 module, uint32 tuple);
|
||||
void stopAudio() { g_system->getMixer()->stopHandle(_audioHandle); }
|
||||
void pauseAudio() { g_system->getMixer()->pauseHandle(_audioHandle, true); }
|
||||
void resumeAudio() { g_system->getMixer()->pauseHandle(_audioHandle, false); }
|
||||
void stopAudio();
|
||||
void pauseAudio();
|
||||
void resumeAudio();
|
||||
|
||||
void setSoundSync(ResourceId id, reg_t syncObjAddr, SegManager *segMan);
|
||||
void doSoundSync(reg_t syncObjAddr, SegManager *segMan);
|
||||
void stopSoundSync();
|
||||
|
||||
int audioCdPlay(int track, int start, int duration);
|
||||
void audioCdStop();
|
||||
void audioCdUpdate();
|
||||
int audioCdPosition();
|
||||
|
||||
void stopAllAudio();
|
||||
|
||||
private:
|
||||
ResourceManager *_resMan;
|
||||
uint16 _audioRate;
|
||||
Audio::SoundHandle _audioHandle;
|
||||
Audio::AudioStream* getAudioStream(uint32 number, uint32 volume, int *sampleLen);
|
||||
Audio::Mixer* _mixer;
|
||||
Resource *_syncResource; /**< Used by kDoSync for speech syncing in CD talkie games */
|
||||
uint _syncOffset;
|
||||
uint32 _audioCdStart;
|
||||
|
||||
Audio::AudioStream* getAudioStream(uint32 number, uint32 volume, int *sampleLen);
|
||||
};
|
||||
|
||||
} // End of namespace Sci
|
||||
|
Loading…
Reference in New Issue
Block a user