aboutsummaryrefslogtreecommitdiff
path: root/sword2
diff options
context:
space:
mode:
authorTorbjörn Andersson2003-08-31 10:38:32 +0000
committerTorbjörn Andersson2003-08-31 10:38:32 +0000
commit155f4591c97704b6d235e8eb397166b3d432cd65 (patch)
treedd619a121ff3a54137d484c8c596c3fdaadfa626 /sword2
parent25a7c5de67d5f8b0b08fa4a3902e0b553d3c35f6 (diff)
downloadscummvm-rg350-155f4591c97704b6d235e8eb397166b3d432cd65.tar.gz
scummvm-rg350-155f4591c97704b6d235e8eb397166b3d432cd65.tar.bz2
scummvm-rg350-155f4591c97704b6d235e8eb397166b3d432cd65.zip
Cleaned up StreamCompMusic(), including some untested endian-fixes.
This should also fix the bug where music sometimes didn't start playing. svn-id: r9938
Diffstat (limited to 'sword2')
-rw-r--r--sword2/driver/d_sound.cpp341
1 files changed, 128 insertions, 213 deletions
diff --git a/sword2/driver/d_sound.cpp b/sword2/driver/d_sound.cpp
index cc683c14bd..1b0bb65090 100644
--- a/sword2/driver/d_sound.cpp
+++ b/sword2/driver/d_sound.cpp
@@ -227,9 +227,10 @@ Sword2Sound::Sword2Sound(SoundMixer *mixer) {
_mixer = mixer;
}
-// --------------------------------------------------------------------------
-// This function reverse the pan table, thus reversing the stereo.
-// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// This function reverse the pan table, thus reversing the stereo.
+// --------------------------------------------------------------------------
+
int32 Sword2Sound::ReverseStereo(void) {
int i,j;
@@ -671,7 +672,7 @@ int32 Sword2Sound::OpenFx(int32 id, uint8 *data) {
i += 1;
data++;
}
- if (i == 100)
+ if (!data32)
return(RDERR_INVALIDWAV);
bufferSizeFx[fxi] = *(data32 + 1);
@@ -757,7 +758,7 @@ int32 Sword2Sound::OpenFx(int32 id, uint8 *data) {
i += 1;
data++;
}
- if (i == 100)
+ if (!data32)
return(RDERR_INVALIDWAV);
dsbd.dwBufferBytes = *(data32 + 1);
@@ -1173,248 +1174,162 @@ void Sword2Sound::StartMusicFadeDown(int i) {
}
int32 Sword2Sound::StreamCompMusic(const char *filename, uint32 musicId, int32 looping) {
- int32 i, z;
- int32 v0, v1;
- uint16 *data16;
- uint8 *data8;
+ int32 primaryStream = -1;
+ int32 secondaryStream = -1;
+ int32 i;
+ int32 v0, v1;
+ uint16 *data16;
+ uint8 *data8;
compressedMusic = 1;
- if (musStreaming[0] + musStreaming[1] == 0) {
- i = 0;
-
- musLooping[i] = looping; // Save looping info
- strcpy(musFilename[i], filename); // And tune id's
- musId[i] = musicId;
-
- if (IsMusicMute()) // Don't start streaming if the volume is off.
- return (RD_OK);
-
- fpMus.open(filename, g_engine->getGameDataPath()); // Always use fpMus[0] (all music in one cluster) musFilePos[i] for different pieces of music.
- if (fpMus.isOpen() == false)
- return(RDERR_INVALIDFILENAME);
-
- fpMus.seek((musicId + 1) * 8, SEEK_SET);
-
- if (fpMus.read(&musFilePos[i], sizeof(uint32)) != sizeof(uint32)) {
- fpMus.close();
- return (RDERR_READERROR);
- }
-
- if (fpMus.read(&musEnd[i], sizeof(uint32)) != sizeof(uint32)) {
- fpMus.close();
- return (RDERR_READERROR);
- }
-
- if (!musEnd[i] || !musFilePos[i]) {
- fpMus.close();
- return (RDERR_INVALIDID);
- }
-
- musEnd[i] += musFilePos[i]; // Calculate the file position of the end of the music
-
- // Create a temporary buffer
- data8 = (uint8*)malloc(bufferSizeMusic / 2);
- if (data8 == NULL) {
- fpMus.close();
- return(RDERR_OUTOFMEMORY);
- }
-
- // Seek to start of the compressed music
- fpMus.seek(musFilePos[i], SEEK_SET);
-
- // Read the compressed data in to the buffer
- if ((int32) fpMus.read(data8, bufferSizeMusic / 2) != bufferSizeMusic / 2) {
- fpMus.close();
- free(data8);
- return (RDERR_INVALIDID);
- }
-
- // Store the current position in the file for future streaming
- musFilePos[i] = fpMus.pos();
-
- // decompress the music into the music buffer.
- data16 = (uint16 *)malloc(bufferSizeMusic);
-
- data16[0] = *((int16 *)data8); // First sample value
- z = 1;
+ // If both music streams are playing, that should mean one of them is
+ // fading out. Pick that one.
- while (z < (bufferSizeMusic / 2) - 1) {
- if (GetCompressedSign(data8[z + 1]))
- data16[z] = data16[z - 1] - (GetCompressedAmplitude(data8[z + 1]) << GetCompressedShift(data8[z + 1]));
- else
- data16[z] = data16[z - 1] + (GetCompressedAmplitude(data8[z + 1]) << GetCompressedShift(data8[z + 1]));
- z++;
- }
-
- // Store the value of the last sample ready for next batch of decompression
- musLastSample[i] = data16[z - 1];
-
- // Free the decompression buffer and unlock the buffer now that we've filled it
- free(data8);
-
- // Modify the volume according to the master volume and music mute state
- if (musicMuted)
- v0 = v1 = 0;
- else {
- v0 = volMusic[0];
- v1 = volMusic[1];
- }
+ if (musStreaming[0] && musStreaming[1]) {
+ if (musFading[0])
+ primaryStream = 0;
+ else
+ primaryStream = 1;
- if (v0 > v1) {
-// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
-// IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
- } else {
- if (v1 > v0) {
-// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
-// IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
- } else {
-// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
-// IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
- }
- }
+ musFading[primaryStream] = 0;
+ g_engine->_mixer->endStream(soundHandleMusic[primaryStream]);
+ musStreaming[primaryStream] = 0;
+ soundHandleMusic[primaryStream] = 0;
+ }
- //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
- for (int32 y = 0; y < (bufferSizeMusic / 2); y++) {
- data16[y] = TO_BE_16(data16[y]);
- }
+ // Pick the available music stream. If no music is playing it doesn't
+ // matter which we use, so pick the first one.
- if (soundHandleMusic[i] == 0) {
- soundHandleMusic[i] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
+ if (musStreaming[0] || musStreaming[1]) {
+ if (musStreaming[0]) {
+ primaryStream = 1;
+ secondaryStream = 0;
} else {
- g_engine->_mixer->appendStream(soundHandleMusic[i], data16, bufferSizeMusic);
+ primaryStream = 0;
+ secondaryStream = 1;
}
+ } else
+ primaryStream = 0;
- free(data16);
+ strcpy(musFilename[primaryStream], filename);
- // Recorder some last variables
- musStreaming[i] = 1;
- musCounter[i] = 250;
- } else if (musStreaming[0] + musStreaming[1] == 2) {
- if (musFading[0])
- i = 0;
- else
- i = 1;
+ // Save looping info and tune id
+ musLooping[primaryStream] = looping;
+ musId[primaryStream] = musicId;
- musFading[i] = 0;
- g_engine->_mixer->endStream(soundHandleMusic[i]);
- musStreaming[i] = 0;
- soundHandleMusic[i] = 0;
- } else if (musStreaming[0] + musStreaming[1] == 1) {
- i = musStreaming[0]; // Set i to the free channel
+ // Don't start streaming if the volume is off.
+ if (IsMusicMute())
+ return RD_OK;
- musLooping[i] = looping; // Save looping info
- strcpy(musFilename[i], filename); // And tune id's
- musId[i] = musicId;
+ // Always use fpMus[0] (all music in one cluster)
+ // musFilePos[primaryStream] for different pieces of music.
+ if (!fpMus.isOpen())
+ fpMus.open(filename, g_engine->getGameDataPath());
- if (IsMusicMute()) // Don't start streaming if the volume is off.
- return (RD_OK);
+ if (!fpMus.isOpen())
+ return RDERR_INVALIDFILENAME;
- if (fpMus.isOpen() == false)
- fpMus.open(filename, g_engine->getGameDataPath()); // Always use fpMus[0] (all music in one cluster) musFilePos[i] for different pieces of music.
- if (fpMus.isOpen() == false)
- return(RDERR_INVALIDFILENAME);
+ // Start other music stream fading out
+ if (secondaryStream != -1 && !musFading[secondaryStream])
+ musFading[secondaryStream] = -16;
- if (!musFading[1 - i]) // Start other music stream fading out
- musFading[1 - i] = -16;
+ fpMus.seek((musicId + 1) * 8, SEEK_SET);
+ musFilePos[primaryStream] = fpMus.readUint32LE();
+ musEnd[primaryStream] = fpMus.readUint32LE();
- fpMus.seek((musicId + 1) * 8, SEEK_SET);
+ if (!musEnd[primaryStream] || !musFilePos[primaryStream]) {
+ fpMus.close();
+ return RDERR_INVALIDID;
+ }
- if (fpMus.read(&musFilePos[i], sizeof(uint32)) != sizeof(uint32)) {
- fpMus.close();
- return (RDERR_READERROR);
- }
+ // Calculate the file position of the end of the music
+ musEnd[primaryStream] += musFilePos[primaryStream];
- if (fpMus.read(&musEnd[i], sizeof(uint32)) != sizeof(uint32)) {
- fpMus.close();
- return (RDERR_READERROR);
- }
+ // Create a temporary buffer
+ data8 = (uint8*) malloc(bufferSizeMusic / 2);
+ if (!data8) {
+ fpMus.close();
+ return RDERR_OUTOFMEMORY;
+ }
- if (!musEnd[i] || !musFilePos[i]) {
- fpMus.close();
- return (RDERR_INVALIDID);
- }
+ // Seek to start of the compressed music
+ fpMus.seek(musFilePos[primaryStream], SEEK_SET);
- musEnd[i] += musFilePos[i]; // Calculate the file position of the end of the music
+ // Read the compressed data in to the buffer
+ if ((int32) fpMus.read(data8, bufferSizeMusic / 2) != bufferSizeMusic / 2) {
+ fpMus.close();
+ free(data8);
+ return RDERR_INVALIDID;
+ }
- // Allocate a compressed data buffer
- data8 = (uint8*)malloc(bufferSizeMusic);
- if (data8 == NULL) {
- fpMus.close();
- return(RDERR_OUTOFMEMORY);
- }
+ // Store the current position in the file for future streaming
+ musFilePos[primaryStream] = fpMus.pos();
- // Seek to start of the compressed music
- fpMus.seek(musFilePos[i], SEEK_SET);
+ // FIXME: We used this decompression function in several places, so
+ // it really should be a separate function.
- // Read the compressed data in to the buffer
- if ((int32) fpMus.read(data8, bufferSizeMusic / 2) != bufferSizeMusic / 2) {
- fpMus.close();
- free(data8);
- return (RDERR_INVALIDID);
- }
-
- // Store the current position in the file for future streaming
- musFilePos[i] = fpMus.pos();
+ // decompress the music into the music buffer.
+ data16 = (uint16 *) malloc(bufferSizeMusic);
+ if (!data16)
+ return RDERR_OUTOFMEMORY;
- // decompress the music into the music buffer.
- data16 = (uint16 *)malloc(bufferSizeMusic);
-
- data16[0] = *((int16 *)data8); // First sample value
- z = 1;
+ data16[0] = READ_LE_UINT16(data8); // First sample value
- while (z < (bufferSizeMusic / 2) - 1) {
- if (GetCompressedSign(data8[z + 1]))
- data16[z] = data16[z - 1] - (GetCompressedAmplitude(data8[z + 1]) << GetCompressedShift(data8[z + 1]));
- else
- data16[z] = data16[z - 1] + (GetCompressedAmplitude(data8[z + 1]) << GetCompressedShift(data8[z + 1]));
- z++;
- }
+ i = 1;
+ while (i < (bufferSizeMusic / 2) - 1) {
+ if (GetCompressedSign(data8[i + 1]))
+ data16[i] = data16[i - 1] - (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
+ else
+ data16[i] = data16[i - 1] + (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
+ i++;
+ }
- // Store the value of the last sample ready for next batch of decompression
- musLastSample[i] = data16[z - 1];
+ // Store the value of the last sample ready for next batch of
+ // decompression
+ musLastSample[primaryStream] = data16[i - 1];
- // Free the compressiong buffer and unlock the buffer now that we've filled it
- free(data8);
+ // Free the compressed sound buffer
+ free(data8);
- // Modify the volume according to the master volume and music mute state
- if (musicMuted)
- v0 = v1 = 0;
- else {
- v0 = volMusic[0];
- v1 = volMusic[1];
- }
+ // Modify the volume according to the master volume and music mute
+ // state
+ if (musicMuted)
+ v0 = v1 = 0;
+ else {
+ v0 = volMusic[0];
+ v1 = volMusic[1];
+ }
- if (v0 > v1) {
-// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
-// IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
- } else {
- if (v1 > v0) {
-// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
-// IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
- } else {
-// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
-// IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
- }
- }
+ if (v0 > v1) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[primaryStream], musicVolTable[v0]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[primaryStream], musicVolTable[v1*16/v0]);
+ } else if (v1 > v0) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[primaryStream], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[primaryStream], -musicVolTable[v0*16/v1]);
+ } else {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[primaryStream], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[primaryStream], 0);
+ }
- //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
- for (int32 y = 0; y < (bufferSizeMusic / 2); y++)
- data16[y] = TO_BE_16(data16[y]);
+ // FIXME: Until the mixer supports LE samples natively, we need to
+ // convert our LE ones to BE
+ for (i = 0; i < (bufferSizeMusic / 2); i++) {
+ data16[i] = TO_BE_16(data16[i]);
+ }
- if (soundHandleMusic[i] == 0) {
- soundHandleMusic[i] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
- } else {
- g_engine->_mixer->appendStream(soundHandleMusic[i], data16, bufferSizeMusic);
- }
+ if (soundHandleMusic[primaryStream] == 0) {
+ soundHandleMusic[primaryStream] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
+ } else {
+ g_engine->_mixer->appendStream(soundHandleMusic[primaryStream], data16, bufferSizeMusic);
+ }
- free(data16);
+ free(data16);
- // Record the last variables for streaming and looping
- musStreaming[i] = 1;
- musCounter[i] = 250;
- }
- return (RD_OK);
+ // Recorder some last variables
+ musStreaming[primaryStream] = 1;
+ musCounter[primaryStream] = 250;
+ return RD_OK;
/*
HRESULT hr;