From a84dfac0d70c5d7251cce8276ea09e9cf2c8cd68 Mon Sep 17 00:00:00 2001 From: Nishi Date: Thu, 28 May 2026 14:07:42 +0900 Subject: [PATCH] 3d audio --- client/main.cc | 2 +- engine/include/fishbone/machdep.h | 1 + engine/include/fishbone/mixer.h | 1 + engine/include/fishbone/sound.h | 7 +++++-- engine/src/mixer.cc | 35 ++++++++++++++++++++++++++++--- engine/src/sound.cc | 9 ++++++-- engine/src/sounddrv/sdl2.cc | 1 + 7 files changed, 48 insertions(+), 8 deletions(-) diff --git a/client/main.cc b/client/main.cc index 6b8bfb9..764e08b 100644 --- a/client/main.cc +++ b/client/main.cc @@ -21,7 +21,7 @@ int main(){ drv = new fishbone::SoundDriver(); - snd = drv->mixer.open("shanghai.ogg"); + snd = drv->mixer.open("music.mod"); snd->setLoop(true); snd->resume(); diff --git a/engine/include/fishbone/machdep.h b/engine/include/fishbone/machdep.h index 0af9a73..90879c8 100644 --- a/engine/include/fishbone/machdep.h +++ b/engine/include/fishbone/machdep.h @@ -6,6 +6,7 @@ #include #include +#include #include diff --git a/engine/include/fishbone/mixer.h b/engine/include/fishbone/mixer.h index 34ec0e0..f7dc895 100644 --- a/engine/include/fishbone/mixer.h +++ b/engine/include/fishbone/mixer.h @@ -25,6 +25,7 @@ namespace fishbone { static const int rate = 44100; std::vector loaders; std::vector sounds; + float position[3]; }; }; // namespace fishbone diff --git a/engine/include/fishbone/sound.h b/engine/include/fishbone/sound.h index 330de47..6e0e873 100644 --- a/engine/include/fishbone/sound.h +++ b/engine/include/fishbone/sound.h @@ -87,8 +87,11 @@ namespace fishbone { void setLoop(bool v); bool isLoop(); - int rate; - int channels; + int rate; + int channels; + float volume; + bool is3d; + float position[3]; }; #define LOADER(X) FB_SOUND_DEF(X); diff --git a/engine/src/mixer.cc b/engine/src/mixer.cc index fef9817..215be28 100644 --- a/engine/src/mixer.cc +++ b/engine/src/mixer.cc @@ -6,6 +6,10 @@ fishbone::Mixer::Mixer() { #define LOADER(X) this->loaders.push_back(new fishbone::X##SoundLoader()); FB_SOUND_LOADERS #undef LOADER + + this->position[0] = 0; + this->position[1] = 0; + this->position[2] = 0; } fishbone::Mixer::~Mixer() { @@ -29,9 +33,30 @@ void fishbone::Mixer::read(short* buffer, size_t frames) { size_t ask; short* req; size_t got; + float la = 1, ra = 1; if(this->sounds[i]->isPaused()) continue; + if(this->sounds[i]->is3d) { + float r[3]; + float angle, v; + float d; + float lf, rf; + + for(int j = 0; j < 3; j++) r[j] = this->sounds[i]->position[j] - this->position[j]; + + angle = atan2(r[2], r[0]); + v = cos(angle); + + lf = 1.0 - v; + rf = 1.0 + v; + + d = sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]); + + la = 1.0 / (1.0 + lf + d * d); + ra = 1.0 / (1.0 + rf + d * d); + } + ask = frames * this->sounds[i]->rate / fishbone::Mixer::rate; req = new short[ask * this->sounds[i]->channels]; got = this->sounds[i]->read(req, ask) * fishbone::Mixer::rate / this->sounds[i]->rate; @@ -39,7 +64,11 @@ void fishbone::Mixer::read(short* buffer, size_t frames) { if(got <= 0) { delete[] req; - this->sounds[i]->pauseNoLock(); + if(this->sounds[i]->isLoop()) { + this->sounds[i]->seek(0); + } else { + this->sounds[i]->pauseNoLock(); + } continue; } @@ -54,8 +83,8 @@ void fishbone::Mixer::read(short* buffer, size_t frames) { r = req[(j * this->sounds[i]->rate / fishbone::Mixer::rate) * 2 + 1]; } - tmp[2 * j + 0] += l / 32767.0; - tmp[2 * j + 1] += r / 32767.0; + tmp[2 * j + 0] += l / 32767.0 * la * this->sounds[i]->volume; + tmp[2 * j + 1] += r / 32767.0 * ra * this->sounds[i]->volume; } delete[] req; diff --git a/engine/src/sound.cc b/engine/src/sound.cc index 80a85fd..dba736a 100644 --- a/engine/src/sound.cc +++ b/engine/src/sound.cc @@ -22,8 +22,13 @@ fishbone::Sound::Sound(fishbone::Mixer* mixer, fishbone::SoundLoader* loader, st this->loader = loader; this->impl = impl; - this->paused = true; - this->loop = false; + this->paused = true; + this->loop = false; + this->volume = 1.0; + this->is3d = false; + this->position[0] = 0; + this->position[1] = 0; + this->position[2] = 0; } int fishbone::Sound::read(short* buffer, size_t frames) { diff --git a/engine/src/sounddrv/sdl2.cc b/engine/src/sounddrv/sdl2.cc index 91a5a85..6e97242 100644 --- a/engine/src/sounddrv/sdl2.cc +++ b/engine/src/sounddrv/sdl2.cc @@ -43,5 +43,6 @@ fishbone::SoundDriver::SoundDriver() { fishbone::SoundDriver::~SoundDriver() { SDL_PauseAudioDevice(this->impl->id, 1); SDL_CloseAudioDevice(this->impl->id); + delete this->impl; } #endif