[Scummvm-cvs-logs] CVS: scummvm/sword2/driver d_sound.cpp,1.142,1.143
Robert Göffringmann
lavosspawn at users.sourceforge.net
Mon Feb 21 00:36:04 CET 2005
Update of /cvsroot/scummvm/scummvm/sword2/driver
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2876/sword2/driver
Modified Files:
d_sound.cpp
Log Message:
basically the same change as for bs1; don't keep the mutex locked while loading mp3, ogg or wave data. it blocks the playing thread for too long.
Also added index caching for the speech and music clusters to reduce seeks.
Index: d_sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/sword2/driver/d_sound.cpp,v
retrieving revision 1.142
retrieving revision 1.143
diff -u -d -r1.142 -r1.143
--- d_sound.cpp 19 Feb 2005 14:02:15 -0000 1.142
+++ d_sound.cpp 21 Feb 2005 08:35:17 -0000 1.143
@@ -40,95 +40,106 @@
static AudioStream *makeCLUStream(File *fp, int size);
-static AudioStream *getAudioStream(File *fp, const char *base, int cd, uint32 id, uint32 *numSamples) {
- struct {
- const char *ext;
- int mode;
- } file_types[] = {
-#ifdef USE_MAD
- { "cl3", kMP3Mode },
-#endif
-#ifdef USE_VORBIS
- { "clg", kVorbisMode },
-#endif
-#ifdef USE_FLAC
- { "clf", kFlacMode },
-#endif
- { "clu", kCLUMode }
- };
+static AudioStream *getAudioStream(SoundFileHandle *fh, const char *base, int cd, uint32 id, uint32 *numSamples) {
+ if (!fh->file->isOpen()) {
+ struct {
+ const char *ext;
+ int mode;
+ } file_types[] = {
+ #ifdef USE_MAD
+ { "cl3", kMP3Mode },
+ #endif
+ #ifdef USE_VORBIS
+ { "clg", kVorbisMode },
+ #endif
+ #ifdef USE_FLAC
+ { "clf", kFlacMode },
+ #endif
+ { "clu", kCLUMode }
+ };
- int soundMode = -1;
- char filename[20];
+ int soundMode = -1;
+ char filename[20];
- for (int i = 0; i < ARRAYSIZE(file_types); i++) {
- File f;
+ for (int i = 0; i < ARRAYSIZE(file_types); i++) {
+ File f;
- sprintf(filename, "%s%d.%s", base, cd, file_types[i].ext);
- if (f.open(filename)) {
- soundMode = file_types[i].mode;
- break;
- }
+ sprintf(filename, "%s%d.%s", base, cd, file_types[i].ext);
+ if (f.open(filename)) {
+ soundMode = file_types[i].mode;
+ break;
+ }
- sprintf(filename, "%s.%s", base, file_types[i].ext);
- if (f.open(filename)) {
- soundMode = file_types[i].mode;
- break;
+ sprintf(filename, "%s.%s", base, file_types[i].ext);
+ if (f.open(filename)) {
+ soundMode = file_types[i].mode;
+ break;
+ }
}
- }
- if (soundMode == 0)
- return NULL;
+ if (soundMode == 0)
+ return NULL;
- // The assumption here is that a sound file is closed when the sound
- // finishes, and we never play sounds from two different files at the
- // same time. Thus, if the file is already open it's the correct file,
- // and the loop above was just needed to figure out the compression.
- //
- // This is to avoid having two file handles open to the same file at
- // the same time. There was some speculation that some of our target
- // systems may have trouble with that.
+ fh->file->open(filename);
+ fh->fileType = soundMode;
+ if (!fh->file->isOpen()) {
+ warning("Very strange fopen error");
+ return NULL;
+ }
+ if (fh->fileSize != fh->file->size()) {
+ if (fh->idxTab) {
+ free(fh->idxTab);
+ fh->idxTab = NULL;
+ }
+ }
+ }
- if (!fp->isOpen())
- fp->open(filename);
+ uint32 entrySize = (fh->fileType == kCLUMode) ? 2 : 3;
- if (!fp->isOpen())
- return NULL;
+ if (!fh->idxTab) {
+ fh->file->seek(0);
+ fh->idxLen = fh->file->readUint32LE();
+ fh->file->seek(entrySize * 4);
- fp->seek((id + 1) * ((soundMode == kCLUMode) ? 8 : 12), SEEK_SET);
+ fh->idxTab = (uint32*)malloc(fh->idxLen * 3 * sizeof(uint32));
+ for (uint32 cnt = 0; cnt < fh->idxLen; cnt++) {
+ fh->idxTab[cnt * 3 + 0] = fh->file->readUint32LE();
+ fh->idxTab[cnt * 3 + 1] = fh->file->readUint32LE();
+ if (fh->fileType == kCLUMode)
+ fh->idxTab[cnt * 3 + 2] = fh->idxTab[cnt * 3 + 1] + 1;
+ else
+ fh->idxTab[cnt * 3 + 2] = fh->file->readUint32LE();
+ }
+ }
- uint32 pos = fp->readUint32LE();
- uint32 len = fp->readUint32LE();
- uint32 enc_len;
+ uint32 pos = fh->idxTab[id * 3 + 0];
+ uint32 len = fh->idxTab[id * 3 + 1];
+ uint32 enc_len = fh->idxTab[id * 3 + 2];
if (numSamples)
*numSamples = len;
- if (soundMode != kCLUMode)
- enc_len = fp->readUint32LE();
- else
- enc_len = len + 1;
-
if (!pos || !len) {
- fp->close();
+ fh->file->close();
return NULL;
}
- fp->seek(pos, SEEK_SET);
+ fh->file->seek(pos, SEEK_SET);
- switch (soundMode) {
+ switch (fh->fileType) {
case kCLUMode:
- return makeCLUStream(fp, enc_len);
+ return makeCLUStream(fh->file, enc_len);
#ifdef USE_MAD
case kMP3Mode:
- return makeMP3Stream(fp, enc_len);
+ return makeMP3Stream(fh->file, enc_len);
#endif
#ifdef USE_VORBIS
case kVorbisMode:
- return makeVorbisStream(fp, enc_len);
+ return makeVorbisStream(fh->file, enc_len);
#endif
#ifdef USE_FLAC
case kFlacMode:
- return makeFlacStream(fp, enc_len);
+ return makeFlacStream(fh->file, enc_len);
#endif
default:
return NULL;
@@ -225,9 +236,9 @@
// The length of a fade-in/out, in milliseconds.
#define FADE_LENGTH 3000
-MusicInputStream::MusicInputStream(int cd, File *fp, uint32 musicId, bool looping) {
+MusicInputStream::MusicInputStream(int cd, SoundFileHandle *fh, uint32 musicId, bool looping) {
_cd = cd;
- _file = fp;
+ _fh = fh;
_musicId = musicId;
_looping = looping;
@@ -235,7 +246,7 @@
_remove = false;
_fading = 0;
- _decoder = getAudioStream(fp, "music", _cd, _musicId, &_numSamples);
+ _decoder = getAudioStream(_fh, "music", _cd, _musicId, &_numSamples);
if (_decoder) {
_samplesLeft = _numSamples;
_fadeSamples = (getRate() * FADE_LENGTH) / 1000;
@@ -353,7 +364,7 @@
if (!_samplesLeft) {
if (_looping) {
delete _decoder;
- _decoder = getAudioStream(_file, "music", _cd, _musicId, &_numSamples);
+ _decoder = getAudioStream(_fh, "music", _cd, _musicId, &_numSamples);
_samplesLeft = _numSamples;
} else
_remove = true;
@@ -448,8 +459,8 @@
}
for (i = 0; i < MAXMUS; i++) {
- if (!inUse[i] && _musicFile[i].isOpen())
- _musicFile[i].close();
+ if (!inUse[i] && !_musicFile[i].inUse && _musicFile[i].file->isOpen())
+ _musicFile[i].file->close();
}
return numSamples;
@@ -457,7 +468,7 @@
bool Sound::endOfData() const {
for (int i = 0; i < MAXMUS; i++) {
- if (_musicFile[i].isOpen())
+ if (_musicFile[i].file->isOpen())
return false;
}
@@ -516,8 +527,9 @@
* @return RD_OK or an error code
*/
int32 Sound::streamCompMusic(uint32 musicId, bool loop) {
- Common::StackLock lock(_mutex);
+ //Common::StackLock lock(_mutex);
+ _mutex.lock();
int cd = _vm->_resman->whichCd();
if (loop)
@@ -572,23 +584,32 @@
primary = 0;
// Don't start streaming if the volume is off.
- if (isMusicMute())
+ if (isMusicMute()) {
+ _mutex.unlock();
return RD_OK;
+ }
if (secondary != -1)
_music[secondary]->fadeDown();
+ SoundFileHandle *fh = (cd == 1) ? &_musicFile[0] : &_musicFile[1];
+ fh->inUse = true;
+ _mutex.unlock();
- File *fp = (cd == 1) ? &_musicFile[0] : &_musicFile[1];
-
- _music[primary] = new MusicInputStream(cd, fp, musicId, loop);
+ MusicInputStream *tmp = new MusicInputStream(cd, fh, musicId, loop);
- if (!_music[primary]->isReady()) {
- delete _music[primary];
- _music[primary] = NULL;
+ if (tmp->isReady()) {
+ _mutex.lock();
+ _music[primary] = tmp;
+ fh->inUse = false;
+ _mutex.unlock();
+ return RD_OK;
+ } else {
+ _mutex.lock();
+ fh->inUse = false;
+ _mutex.unlock();
+ delete tmp;
return RDERR_INVALIDFILENAME;
}
-
- return RD_OK;
}
/**
@@ -685,10 +706,12 @@
*/
uint32 Sound::preFetchCompSpeech(uint32 speechId, uint16 **buf) {
- File fp;
+ int cd = _vm->_resman->whichCd();
uint32 numSamples;
- AudioStream *input = getAudioStream(&fp, "speech", _vm->_resman->whichCd(), speechId, &numSamples);
+ SoundFileHandle *fh = (cd == 1) ? &_speechFile[0] : &_speechFile[1];
+
+ AudioStream *input = getAudioStream(fh, "speech", cd, speechId, &numSamples);
if (!input)
return 0;
@@ -702,13 +725,13 @@
*buf = (uint16 *) malloc(bufferSize);
if (!*buf) {
delete input;
- fp.close();
+ fh->file->close();
return 0;
}
uint32 readSamples = input->readBuffer((int16 *) *buf, numSamples);
- fp.close();
+ fh->file->close();
delete input;
return 2 * readSamples;
@@ -729,12 +752,10 @@
if (getSpeechStatus() == RDERR_SPEECHPLAYING)
return RDERR_SPEECHPLAYING;
- File *fp = new File;
- AudioStream *input = getAudioStream(fp, "speech", _vm->_resman->whichCd(), speechId, NULL);
+ int cd = _vm->_resman->whichCd();
+ SoundFileHandle *fh = (cd == 1) ? &_speechFile[0] : &_speechFile[1];
- // Make the AudioStream object the sole owner of the file so that it
- // will die along with the AudioStream when the speech has finished.
- fp->decRef();
+ AudioStream *input = getAudioStream(fh, "speech", cd, speechId, NULL);
if (!input)
return RDERR_INVALIDID;
More information about the Scummvm-git-logs
mailing list