aboutsummaryrefslogtreecommitdiff
path: root/sword1
diff options
context:
space:
mode:
authorRobert Göffringmann2003-12-22 02:47:43 +0000
committerRobert Göffringmann2003-12-22 02:47:43 +0000
commit44f1ed75fd76fd9842acd5784a31672a37536996 (patch)
tree6957d1ab269dfbc80dd33416dadef0a33830f3a3 /sword1
parentfd4417e6bbe0a571e51c1cb82e9941c455b9ce76 (diff)
downloadscummvm-rg350-44f1ed75fd76fd9842acd5784a31672a37536996.tar.gz
scummvm-rg350-44f1ed75fd76fd9842acd5784a31672a37536996.tar.bz2
scummvm-rg350-44f1ed75fd76fd9842acd5784a31672a37536996.zip
added code for non-looping music and implemented fading
svn-id: r11845
Diffstat (limited to 'sword1')
-rw-r--r--sword1/music.cpp145
-rw-r--r--sword1/music.h12
2 files changed, 118 insertions, 39 deletions
diff --git a/sword1/music.cpp b/sword1/music.cpp
index 98a1b69000..9ec8358ecc 100644
--- a/sword1/music.cpp
+++ b/sword1/music.cpp
@@ -32,12 +32,14 @@ SwordMusic::SwordMusic(OSystem *system, SoundMixer *pMixer) {
_system = system;
_mixer = pMixer;
_mixer->setupPremix(passMixerFunc, this);
- _fading = 0;
+ _fading = false;
_playing = false;
_loop = false;
_mutex = _system->create_mutex();
- _waveSize = _wavePos = _bufPos = _smpInBuf = 0;
+ _fadeSmpInBuf = _fadeBufPos = _waveSize = _wavePos = _bufPos = _smpInBuf = 0;
assert(_mixer->getOutputRate() == 22050);
+ _fadeBuf = NULL;
+ _musicBuf = NULL;
}
SwordMusic::~SwordMusic() {
@@ -48,51 +50,103 @@ void SwordMusic::passMixerFunc(void *param, int16 *buf, uint len) {
((SwordMusic*)param)->mixer(buf, len);
}
-void SwordMusic::mixer(int16 *buf, uint len) {
+void SwordMusic::mixTo(int16 *src, int16 *dst, uint32 len) {
if (!_playing)
- memset(buf, 0, 2 * len * sizeof(int16));
- else {
- _system->lock_mutex(_mutex);
- len >>= 1;
- if (len <= _smpInBuf) {
- uint32 maxLen = BUFSIZE - _bufPos;
- if (len >= maxLen) {
- for (uint32 cnt = 0; cnt < maxLen; cnt++)
- buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] =
- buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = (int16)READ_LE_UINT16(_musicBuf + _bufPos + cnt);
- _smpInBuf -= maxLen;
- _bufPos = 0;
- len -= maxLen;
- buf += maxLen * 4;
+ memset(dst, 0, len * 8);
+ if (!_fading) { // no fading, simply copy it over
+ for (uint32 cnt = 0; cnt < len; cnt++)
+ dst[(cnt << 2) | 0] = dst[(cnt << 2) | 1] =
+ dst[(cnt << 2) | 2] = dst[(cnt << 2) | 3] = (int16)READ_LE_UINT16(src + cnt);
+ } else {
+ if (_fadeBuf) { // do a cross fade
+ for (uint32 cnt = 0; cnt < len; cnt++) {
+ int16 resVal = ((int16)READ_LE_UINT16(_fadeBuf + _fadeBufPos) * _fadeVal) >> 15;
+ resVal += ((int16)READ_LE_UINT16(src + cnt) * (32768 - _fadeVal)) >> 15;
+ dst[(cnt << 2) | 0] = dst[(cnt << 2) | 1] =
+ dst[(cnt << 2) | 2] = dst[(cnt << 2) | 3] = resVal;
+ _fadeVal--;
+ _fadeBufPos++;
+ _fadeSmpInBuf--;
+ }
+ if ((!_fadeVal) || (!_fadeSmpInBuf)) {
+ free(_fadeBuf);
+ _fadeBuf = NULL;
+ _fading = false;
}
- if (len) {
- for (uint32 cnt = 0; cnt < len; cnt++)
- buf[(cnt << 2) | 0] = buf[(cnt << 2) | 1] =
- buf[(cnt << 2) | 2] = buf[(cnt << 2) | 3] = (int16)READ_LE_UINT16(_musicBuf + _bufPos + cnt);
- _smpInBuf -= len;
- _bufPos += len;
+ if (_fadeBufPos == BUFSIZE)
+ _fadeBufPos = 0;
+ } else { // simple fadeout
+ for (uint32 cnt = 0; cnt < len; cnt++) {
+ dst[(cnt << 2) | 0] = dst[(cnt << 2) | 1] =
+ dst[(cnt << 2) | 2] = dst[(cnt << 2) | 3] =
+ ((int16)READ_LE_UINT16(src + cnt) * _fadeVal) >> 15;
+ _fadeVal--;
+ }
+ if (!_fadeVal) {
+ _fading = _playing = false;
+ free(_musicBuf);
+ _musicBuf = NULL;
}
}
- _system->unlock_mutex(_mutex);
}
}
+void SwordMusic::mixer(int16 *buf, uint32 len) {
+ if (!_playing) {
+ memset(buf, 0, 2 * len * sizeof(int16));
+ return;
+ }
+ uint32 remain = 0;
+ if (_smpInBuf < (len >> 1)) {
+ if (_loop)
+ return;
+ remain = (len >> 1) - _smpInBuf;
+ len = _smpInBuf << 1;
+ }
+ _system->lock_mutex(_mutex);
+ len >>= 1;
+ while (len) {
+ uint32 length = len;
+ length = MIN(length, BUFSIZE - _bufPos);
+ if (_fading) {
+ length = MIN(length, (uint32)_fadeVal);
+ length = MIN(length, _fadeSmpInBuf);
+ length = MIN(length, BUFSIZE - _fadeBufPos);
+ }
+ mixTo(_musicBuf + _bufPos, buf, length);
+ len -= length;
+ buf += 4 * length;
+ _bufPos += length;
+ _smpInBuf -= length;
+ if (_bufPos == BUFSIZE)
+ _bufPos = 0;
+ }
+ if (remain) {
+ memset(buf, 0, remain * 8);
+ _playing = false;
+ }
+ _system->unlock_mutex(_mutex);
+}
+
void SwordMusic::stream(void) {
// make sure we've got enough samples in buffer.
- if ((_smpInBuf < SAMPLERATE) && _playing) {
+ if ((_smpInBuf < 4 * SAMPLERATE) && _playing) {
_system->lock_mutex(_mutex);
uint32 loadTotal = BUFSIZE - _smpInBuf;
while (uint32 doLoad = loadTotal) {
if (BUFSIZE - ((_bufPos + _smpInBuf) % BUFSIZE) < loadTotal)
doLoad = BUFSIZE - (_bufPos + _smpInBuf) % BUFSIZE;
- if (_waveSize - _wavePos < doLoad)
- doLoad = _waveSize - _wavePos;
+ doLoad = MIN(doLoad, _waveSize - _wavePos);
+
int16 *dest = _musicBuf + ((_bufPos + _smpInBuf) % BUFSIZE);
_musicFile.read(dest, doLoad * 2);
_wavePos += doLoad;
if (_wavePos == _waveSize) {
- _wavePos = 0;
- _musicFile.seek(WAVEHEADERSIZE);
+ if (_loop) {
+ _wavePos = 0;
+ _musicFile.seek(WAVEHEADERSIZE);
+ } else
+ loadTotal = doLoad;
}
loadTotal -= doLoad;
_smpInBuf += doLoad;
@@ -104,28 +158,49 @@ void SwordMusic::stream(void) {
void SwordMusic::startMusic(int32 tuneId, int32 loopFlag) {
_system->lock_mutex(_mutex);
_loop = (loopFlag > 0);
- if (tuneId) {
+ if (tuneId) {
if (_musicFile.isOpen())
_musicFile.close();
char fName[20];
sprintf(fName, "music/%s.wav", _tuneList[tuneId]);
_musicFile.open(fName);
if (_musicFile.isOpen()) {
+ if (_playing) { // do a cross fade
+ _fadeBuf = _musicBuf;
+ _fadeBufPos = _bufPos;
+ _fadeSmpInBuf = _smpInBuf;
+ _fading = true;
+ _fadeVal = 32768;
+ } else
+ _fading = false;
+ _musicBuf = (int16*)malloc(BUFSIZE * 2);
+
_musicFile.seek(0x28);
_waveSize = _musicFile.readUint32LE() / 2;
_wavePos = 0;
_smpInBuf = 0;
_bufPos = 0;
_playing = true;
- } else
- _playing = false;
- } else
- _playing = false;
+ } else {
+ _fading = true;
+ _fadeVal = 32768;
+ if (_fadeBuf) {
+ free(_fadeBuf);
+ _fadeBuf = NULL;
+ }
+ }
+ } else if (_playing)
+ fadeDown();
_system->unlock_mutex(_mutex);
stream();
}
void SwordMusic::fadeDown(void) {
- warning("stub: SwordMusic::fadeDown");
+ _fadeVal = 32768;
+ _fading = true;
+ if (_fadeBuf) {
+ free(_fadeBuf);
+ _fadeBuf = NULL;
+ }
}
diff --git a/sword1/music.h b/sword1/music.h
index f273faf7cc..1b98239e76 100644
--- a/sword1/music.h
+++ b/sword1/music.h
@@ -28,7 +28,7 @@
#define TOTAL_TUNES 270
#define SAMPLERATE 11025
-#define BUFSIZE (4 * SAMPLERATE)
+#define BUFSIZE (6 * SAMPLERATE)
#define WAVEHEADERSIZE 0x2C
class SoundMixer;
@@ -44,16 +44,20 @@ private:
File _musicFile;
OSystem *_system;
SoundMixer *_mixer;
- uint16 _fading;
+ bool _fading;
+ uint16 _fadeVal;
bool _playing;
bool _loop;
OSystem::MutexRef _mutex;
static void passMixerFunc(void *param, int16 *buf, uint len);
- void mixer(int16 *buf, uint len);
+ void mixTo(int16 *src, int16 *dst, uint32 len);
+ void mixer(int16 *buf, uint32 len);
static const char _tuneList[TOTAL_TUNES][8]; // in staticres.cpp
uint32 _waveSize, _wavePos;
+ int16 *_musicBuf; // samples for 6 seconds
uint32 _bufPos, _smpInBuf;
- int16 _musicBuf[BUFSIZE]; // samples for 8 seconds
+ int16 *_fadeBuf;
+ uint32 _fadeBufPos, _fadeSmpInBuf;
};
#endif // BSMUSIC_H