TWP: Add sound panning

This commit is contained in:
scemino 2024-01-15 22:57:28 +01:00 committed by Eugene Sandulenko
parent dc52874c07
commit e729524698
6 changed files with 46 additions and 15 deletions

View file

@ -28,6 +28,7 @@
#include "twp/audio.h"
#include "twp/twp.h"
#include "twp/ids.h"
#include "twp/squtil.h"
namespace Twp {
@ -154,6 +155,28 @@ void AudioSystem::updateVolume(AudioSlot *slot) {
return;
}
}
if (slot->objId) {
Object *obj = sqobj(slot->objId);
if (obj) {
float volObj = 0.f;
if (obj->_room == g_engine->_room) {
float width = g_engine->_room->getScreenSize().getX();
float x = g_engine->cameraPos().getX();
float diff = abs(x - obj->_node->getAbsPos().getX());
if (diff > (1.5f * width)) {
volObj = 0.f;
} else if (diff < (0.25f * width)) {
volObj = 1.f;
} else {
volObj = (width - (diff - (0.25f * width))) / width;
}
float pan = clamp((obj->_node->getAbsPos().getX() - x) / (width / 2), -1.0f, 1.0f);
g_engine->_mixer->setChannelBalance(slot->handle, (int8)(pan * 127));
}
vol *= volObj;
}
}
g_engine->_mixer->setChannelVolume(slot->handle, vol * Audio::Mixer::kMaxChannelVolume);
}
@ -225,6 +248,7 @@ int AudioSystem::play(SoundDefinition *sndDef, Audio::Mixer::SoundType cat, int
}
g_engine->_mixer->playStream(cat, &slot->handle, audioStream, id, vol * _masterVolume);
slot->id = id;
slot->objId = objId;
slot->sndDef = sndDef;
slot->busy = true;
slot->volume = volume;

View file

@ -77,15 +77,16 @@ private:
};
struct AudioSlot {
Audio::SoundHandle handle;
SoundDefinition *sndDef = nullptr;
SoundStream stream;
bool busy = false;
float volume = 1.f;
float fadeInTimeMs = 0.f;
float fadeOutTimeMs = 0.f;
Audio::SoundHandle handle; // handle returned when this sound has been played
SoundDefinition *sndDef = nullptr; // sound definition associated to this slot
SoundStream stream; // audio stream
bool busy = false; // is sound active
float volume = 1.f; // actual volume for this slot
float fadeInTimeMs = 0.f; // fade-in time in milliseconds
float fadeOutTimeMs = 0.f; // fade-out time in milliseconds
int total = 0;
int id = 0;
int id = 0; // unique sound ID
int objId = 0; // object ID or 0 if none
};
class AudioSystem {

View file

@ -330,7 +330,7 @@ int Talking::loadActorSpeech(const Common::String &name) {
debug("File %s.ogg not found", name.c_str());
} else {
g_engine->_audio._soundDefs.push_back(soundDefinition);
return g_engine->_audio.play(soundDefinition, Audio::Mixer::SoundType::kSpeechSoundType, 0, 0, 1.f, _obj->getId());
return g_engine->_audio.play(soundDefinition, Audio::Mixer::SoundType::kSpeechSoundType, 0, 0, 1.f);
}
}
return 0;

View file

@ -32,16 +32,17 @@ namespace Twp {
class SoundTrigger : public Trigger {
public:
SoundTrigger(const Common::Array<SoundDefinition *> sounds) : _sounds(sounds) {}
SoundTrigger(const Common::Array<SoundDefinition *> sounds, int objId) : _sounds(sounds), _objId(objId) {}
virtual ~SoundTrigger() {}
virtual void trig() override {
int i = g_engine->getRandomSource().getRandomNumber(_sounds.size() - 1);
g_engine->_audio.play(_sounds[i], Audio::Mixer::SoundType::kPlainSoundType);
g_engine->_audio.play(_sounds[i], Audio::Mixer::SoundType::kPlainSoundType, 0, 0.f, 0.f, _objId);
}
private:
const Common::Array<SoundDefinition *> _sounds;
int _objId;
};
// Plays a sound at the specified actor's location.
@ -72,7 +73,7 @@ static SQInteger actorSound(HSQUIRRELVM v) {
}
}
Trigger *trigger = new SoundTrigger(sounds);
Trigger *trigger = new SoundTrigger(sounds, obj->getId());
obj->_triggers[trigNum] = trigger;
}
}
@ -141,7 +142,7 @@ static SQInteger playObjectSound(HSQUIRRELVM v) {
g_engine->_audio.stop(obj->_sound);
}
int soundId = g_engine->_audio.play(soundDef, Audio::Mixer::SoundType::kPlainSoundType, loopTimes, fadeInTime, obj->getId());
int soundId = g_engine->_audio.play(soundDef, Audio::Mixer::SoundType::kPlainSoundType, loopTimes, fadeInTime, 1.f, obj->getId());
obj->_sound = soundId;
sqpush(v, soundId);
return 1;

View file

@ -287,8 +287,7 @@ Room *sqroom(HSQUIRRELVM v, int i) {
return nullptr;
}
Object *sqobj(HSQOBJECT table) {
int id = getId(table);
Object *sqobj(int id) {
for (int i = 0; i < g_engine->_actors.size(); i++) {
Object *actor = g_engine->_actors[i];
if (getId(actor->_table) == id)
@ -309,6 +308,11 @@ Object *sqobj(HSQOBJECT table) {
return nullptr;
}
Object *sqobj(HSQOBJECT table) {
int id = getId(table);
return sqobj(id);
}
Object *sqobj(HSQUIRRELVM v, int i) {
HSQOBJECT table;
sq_getstackobj(v, i, &table);

View file

@ -159,6 +159,7 @@ Room *sqroom(HSQOBJECT table);
Room *sqroom(HSQUIRRELVM v, int i);
Object *sqobj(HSQOBJECT table);
Object *sqobj(HSQUIRRELVM v, int i);
Object *sqobj(int i);
Object *sqactor(HSQOBJECT table);
Object *sqactor(HSQUIRRELVM v, int i);
SoundDefinition* sqsounddef(HSQUIRRELVM v, int i);