aboutsummaryrefslogtreecommitdiff
path: root/engines/bladerunner/ambient_sounds.cpp
diff options
context:
space:
mode:
authorPeter Kohaut2017-08-24 23:43:47 +0200
committerPeter Kohaut2017-08-24 23:43:47 +0200
commit0da18320af79b6ca8a47248442d106674b5ab860 (patch)
tree504d769edcf92fc4cbceddfbcdda038ecc040ced /engines/bladerunner/ambient_sounds.cpp
parentc9b4089ccb0b60389446e07f7f9421e3a7180129 (diff)
downloadscummvm-rg350-0da18320af79b6ca8a47248442d106674b5ab860.tar.gz
scummvm-rg350-0da18320af79b6ca8a47248442d106674b5ab860.tar.bz2
scummvm-rg350-0da18320af79b6ca8a47248442d106674b5ab860.zip
BLADERUNNER: Added audio mixer & various fixes
Audio mixer is supporting fading and pan animation Added support for skipping speech by pressing Return Added proper support for ambient sounds Added more code to the dialogue menu Added tooltips to the Spinner Fixed calculation of volume and pan of walk steps Code cleanup & formatting
Diffstat (limited to 'engines/bladerunner/ambient_sounds.cpp')
-rw-r--r--engines/bladerunner/ambient_sounds.cpp258
1 files changed, 190 insertions, 68 deletions
diff --git a/engines/bladerunner/ambient_sounds.cpp b/engines/bladerunner/ambient_sounds.cpp
index aaf6c016d3..7790b03506 100644
--- a/engines/bladerunner/ambient_sounds.cpp
+++ b/engines/bladerunner/ambient_sounds.cpp
@@ -34,7 +34,7 @@ namespace BladeRunner {
#define NON_LOOPING_SOUNDS 25
#define LOOPING_SOUNDS 3
-AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) : _vm(vm) {
+AmbientSounds::AmbientSounds(BladeRunnerEngine *vm) : _vm(vm) {
_nonLoopingSounds = new NonLoopingSound[NON_LOOPING_SOUNDS];
_loopingSounds = new LoopingSound[LOOPING_SOUNDS];
_ambientVolume = 65;
@@ -64,45 +64,133 @@ static inline void sort(int &a, int &b) {
}
void AmbientSounds::addSound(
- int id,
- int timeRangeBegin, int timeRangeEnd,
- int volumeRangeBegin, int volumeRangeEnd,
- int unk1RangeBegin, int unk1RangeEnd,
- int unk2RangeBegin, int unk2RangeEnd,
- int priority, int unk3) {
- const char *name = _vm->_gameInfo->getSfxTrack(id);
-
- sort(volumeRangeBegin, volumeRangeEnd);
- sort(unk1RangeBegin, unk1RangeEnd);
- sort(unk2RangeBegin, unk2RangeEnd);
+ int sfxId,
+ int timeMin, int timeMax,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk) {
+ const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
+
+ sort(volumeMin, volumeMax);
+ sort(panStartMin, panStartMax);
+ sort(panEndMin, panEndMax);
addSoundByName(
- name,
- timeRangeBegin, timeRangeEnd,
- volumeRangeBegin, volumeRangeEnd,
- unk1RangeBegin, unk1RangeEnd,
- unk2RangeBegin, unk2RangeEnd,
- priority, unk3
- );
+ name,
+ timeMin, timeMax,
+ volumeMin, volumeMax,
+ panStartMin, panStartMax,
+ panEndMin, panEndMax,
+ priority, unk
+ );
}
-void AmbientSounds::addLoopingSound(int sfx_id, int volume, int unk, int fadeInTime) {
- const char *name = _vm->_gameInfo->getSfxTrack(sfx_id);
+void AmbientSounds::removeNonLoopingSound(int sfxId, bool stopPlaying) {
+ const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
+ int32 hash = mix_id(name);
+ int index = findNonLoopingTrackByHash(hash);
+ if (index >= 0) {
+ removeNonLoopingSoundByIndex(index, stopPlaying);
+ }
+}
+
+void AmbientSounds::removeAllNonLoopingSounds(bool stopPlaying) {
+ for (int i = 0; i < NON_LOOPING_SOUNDS; i++) {
+ removeNonLoopingSoundByIndex(i, stopPlaying);
+ }
+}
+
+void AmbientSounds::addSpeech(int actorId, int sentenceId, int timeMin, int timeMax, int volumeMin, int volumeMax, int panStartMin, int panStartMax, int panEndMin, int panEndMax, int priority, int unk) {
+ sort(volumeMin, volumeMax);
+ sort(panStartMin, panStartMax);
+ sort(panEndMin, panEndMax);
+
+ char name[13];
+ sprintf(name, "%02d-%04d.AUD", actorId, sentenceId); //TODO somewhere here should be also language code
+ addSoundByName(name,
+ timeMin, timeMax,
+ volumeMin, volumeMax,
+ panStartMin, panStartMax,
+ panEndMin, panEndMax,
+ priority, unk);
+}
+
+void AmbientSounds::playSound(int sfxId, int volume, int panStart, int panEnd, int priority) {
+ const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
+
+ _vm->_audioPlayer->playAud(name, volume * _ambientVolume / 100, panStart, panEnd, priority, AudioPlayer::OVERRIDE_VOLUME);
+}
+
+void AmbientSounds::addLoopingSound(int sfxId, int volume, int pan, int delay) {
+ const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
int32 hash = mix_id(name);
- if (findLoopingTrackByHash(hash) >= 0)
+ if (findLoopingTrackByHash(hash) >= 0) {
return;
+ }
int i = findAvailableLoopingTrack();
- if (i == -1)
+ if (i == -1) {
return;
+ }
+ LoopingSound &track = _loopingSounds[i];
+
+ track.isActive = true;
+ strcpy(track.name, name);
+ track.hash = hash;
+ track.pan = pan;
+ track.volume = volume;
+
+ int actualVolumeStart = volume * _ambientVolume / 100;
+ int actualVolumeEnd = actualVolumeStart;
+
+ if (delay > 0) {
+ actualVolumeStart = 0;
+ }
+
+ track.audioPlayerTrack = _vm->_audioPlayer->playAud(name, actualVolumeStart, pan, pan, 99, AudioPlayer::LOOP | AudioPlayer::OVERRIDE_VOLUME);
+
+ if (track.audioPlayerTrack == -1) {
+ removeLoopingSoundByIndex(i, 0);
+ } else {
+ if (delay) {
+ _vm->_audioPlayer->adjustVolume(track.audioPlayerTrack, actualVolumeEnd, delay, false);
+ }
+ }
+}
+
+void AmbientSounds::adjustLoopingSound(int sfxId, int volume, int pan, int delay) {
+ const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
+ int32 hash = mix_id(name);
+ int index = findLoopingTrackByHash(hash);
- int actualVolume = volume * _ambientVolume / 100;
+ if (index >= 0 && _loopingSounds[index].audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(_loopingSounds[index].audioPlayerTrack)) {
+ if (volume != -1) {
+ _loopingSounds[index].volume = volume;
+ _vm->_audioPlayer->adjustVolume(_loopingSounds[index].audioPlayerTrack, _ambientVolume * volume / 100, delay, false);
+ }
+ if (pan != -101) {
+ _loopingSounds[index].pan = pan;
+ _vm->_audioPlayer->adjustPan(_loopingSounds[index].audioPlayerTrack, pan, delay);
+ }
+ }
+}
- int balance = 0;
+void AmbientSounds::removeLoopingSound(int sfxId, int delay) {
+ const char *name = _vm->_gameInfo->getSfxTrack(sfxId);
+ int32 hash = mix_id(name);
+ int index = findLoopingTrackByHash(hash);
+ if (index >= 0) {
+ removeLoopingSoundByIndex(index, delay);
+ }
+}
- _vm->_audioPlayer->playAud(name, actualVolume, balance, balance, 100, AudioPlayer::LOOP | AudioPlayer::OVERRIDE_VOLUME);
+void AmbientSounds::removeAllLoopingSounds(int delay) {
+ for (int i = 0; i < LOOPING_SOUNDS; i++) {
+ removeLoopingSoundByIndex(i, delay);
+ }
}
void AmbientSounds::tick() {
@@ -111,37 +199,38 @@ void AmbientSounds::tick() {
for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) {
NonLoopingSound &track = _nonLoopingSounds[i];
- if (!track.isActive || track.nextPlayTime > now)
+ if (!track.isActive || track.nextPlayTime > now) {
continue;
+ }
- int pan1, pan2;
-
- pan1 = _vm->_rnd.getRandomNumberRng(track.pan1begin, track.pan1end);
- if (track.pan2begin == -101) {
- pan2 = pan1;
+ int panEnd;
+ int panStart = _vm->_rnd.getRandomNumberRng(track.panStartMin, track.panStartMax);
+ if (track.panEndMin == -101) {
+ panEnd = panStart;
} else {
- pan2 = _vm->_rnd.getRandomNumberRng(track.pan2begin, track.pan2end);
+ panEnd = _vm->_rnd.getRandomNumberRng(track.panEndMin, track.panEndMax);
}
- track.volume = _vm->_rnd.getRandomNumberRng(track.volume1, track.volume2);
+ track.volume = _vm->_rnd.getRandomNumberRng(track.volumeMin, track.volumeMax);
- track.audio_player_track = _vm->_audioPlayer->playAud(
- track.name,
- track.volume * _ambientVolume / 100,
- pan1, pan2,
- track.priority,
- AudioPlayer::OVERRIDE_VOLUME
- );
-
- track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.time1, track.time2);
+ track.audioPlayerTrack = _vm->_audioPlayer->playAud(
+ track.name,
+ track.volume * _ambientVolume / 100,
+ panStart,
+ panEnd,
+ track.priority,
+ AudioPlayer::OVERRIDE_VOLUME
+ );
+ track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.timeMin, track.timeMax);
}
}
int AmbientSounds::findAvailableNonLoopingTrack() {
for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) {
- if (!_nonLoopingSounds[i].isActive)
+ if (!_nonLoopingSounds[i].isActive) {
return i;
+ }
}
return -1;
@@ -151,8 +240,9 @@ int AmbientSounds::findNonLoopingTrackByHash(int32 hash) {
for (int i = 0; i != NON_LOOPING_SOUNDS; ++i) {
NonLoopingSound &track = _nonLoopingSounds[i];
- if (track.isActive && track.hash == hash)
+ if (track.isActive && track.hash == hash) {
return i;
+ }
}
return -1;
@@ -160,8 +250,9 @@ int AmbientSounds::findNonLoopingTrackByHash(int32 hash) {
int AmbientSounds::findAvailableLoopingTrack() {
for (int i = 0; i != LOOPING_SOUNDS; ++i) {
- if (!_loopingSounds[i].isActive)
+ if (!_loopingSounds[i].isActive) {
return i;
+ }
}
return -1;
@@ -171,46 +262,77 @@ int AmbientSounds::findLoopingTrackByHash(int32 hash) {
for (int i = 0; i != LOOPING_SOUNDS; ++i) {
LoopingSound &track = _loopingSounds[i];
- if (track.isActive && track.hash == hash)
+ if (track.isActive && track.hash == hash) {
return i;
+ }
}
return -1;
}
void AmbientSounds::addSoundByName(
- const char *name,
- int timeRangeBegin, int timeRangeEnd,
- int volumeRangeBegin, int volumeRangeEnd,
- int pan1begin, int pan1end,
- int pan2begin, int pan2end,
- int priority, int unk3) {
+ const char *name,
+ int timeMin, int timeMax,
+ int volumeMin, int volumeMax,
+ int panStartMin, int panStartMax,
+ int panEndMin, int panEndMax,
+ int priority, int unk) {
if (strlen(name) > 12) {
error("AmbientSounds::addSoundByName: Overlong name '%s'", name);
}
int i = findAvailableNonLoopingTrack();
- if (i < 0)
+ if (i < 0) {
return;
+ }
NonLoopingSound &track = _nonLoopingSounds[i];
- uint32 now = g_system->getMillis();
+ uint32 now = _vm->getTotalPlayTime();
- track.isActive = true;
+ track.isActive = true;
strcpy(track.name, name);
- track.hash = mix_id(name);
- track.time1 = 1000 * timeRangeBegin;
- track.time2 = 1000 * timeRangeEnd;
- track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.time1, track.time2);
- track.volume1 = volumeRangeBegin;
- track.volume2 = volumeRangeEnd;
- track.volume = 0;
- track.pan1begin = pan1begin;
- track.pan1end = pan1end;
- track.pan2begin = pan2begin;
- track.pan2end = pan2end;
- track.priority = priority;
+ track.hash = mix_id(name);
+ track.timeMin = 1000 * timeMin;
+ track.timeMax = 1000 * timeMax;
+ track.nextPlayTime = now + _vm->_rnd.getRandomNumberRng(track.timeMin, track.timeMax);
+ track.volumeMin = volumeMin;
+ track.volumeMax = volumeMax;
+ track.volume = 0;
+ track.panStartMin = panStartMin;
+ track.panStartMax = panStartMax;
+ track.panEndMin = panEndMin;
+ track.panEndMax = panEndMax;
+ track.priority = priority;
+}
+
+void AmbientSounds::removeNonLoopingSoundByIndex(int index, bool stopPlaying) {
+ NonLoopingSound &track = _nonLoopingSounds[index];
+ if (stopPlaying) {
+ if (track.isActive && track.audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(track.audioPlayerTrack)) {
+ _vm->_audioPlayer->stop(track.audioPlayerTrack, stopPlaying);
+ }
+ }
+ track.isActive = false;
+ track.audioPlayerTrack = -1;
+ // track.field_45 = 0;
+}
+
+void AmbientSounds::removeLoopingSoundByIndex(int index, int delay) {
+ LoopingSound &track = _loopingSounds[index];
+ if (track.isActive && track.audioPlayerTrack != -1 && _vm->_audioPlayer->isActive(track.audioPlayerTrack)) {
+ if (delay > 0) {
+ _vm->_audioPlayer->adjustVolume(track.audioPlayerTrack, 0, delay, false);
+ } else {
+ _vm->_audioPlayer->stop(track.audioPlayerTrack, false);
+ }
+ }
+ track.isActive = false;
+ track.name[0] = 0;
+ track.hash = 0;
+ track.audioPlayerTrack = -1;
+ track.volume = 0;
+ track.pan = 0;
}
} // End of namespace BladeRunner