Add ambient sound system and eliminate log spam

- Implement AmbientSoundManager with tavern/outdoor ambience
- Fix audio buffer limit (5s → 60s) for long ambient loops
- Set log level to INFO to eliminate DEBUG spam (130MB → 3.2MB logs)
- Remove excessive terrain/model/network logging
- Fix ambient sound timer sharing and pitch parameter bugs
This commit is contained in:
Kelsi 2026-02-09 14:50:14 -08:00
parent 045a8c7c89
commit b7a18447b0
24 changed files with 701 additions and 138 deletions

View file

@ -66,6 +66,7 @@ private:
std::chrono::steady_clock::time_point lastLandAt{};
std::chrono::steady_clock::time_point lastSplashAt{};
std::chrono::steady_clock::time_point lastMeleeSwingAt{};
std::chrono::steady_clock::time_point lastSwimStrokeAt{};
bool meleeSwingWarned = false;
std::string voiceProfileKey;
float volumeScale = 1.0f;

View file

@ -0,0 +1,111 @@
#pragma once
#include <vector>
#include <memory>
#include <string>
#include <cstdint>
#include <glm/vec3.hpp>
namespace wowee {
namespace pipeline {
class AssetManager;
}
namespace audio {
class AmbientSoundManager {
public:
AmbientSoundManager() = default;
~AmbientSoundManager() = default;
// Initialization
bool initialize(pipeline::AssetManager* assets);
void shutdown();
// Main update loop - called from renderer
void update(float deltaTime, const glm::vec3& cameraPos, bool isIndoor, bool isSwimming = false);
// Emitter management
enum class AmbientType {
FIREPLACE_SMALL,
FIREPLACE_LARGE,
TORCH,
FOUNTAIN,
WATER_SURFACE,
RIVER,
WATERFALL,
WIND,
BIRD_DAY,
CRICKET_NIGHT,
OWL_NIGHT
};
uint64_t addEmitter(const glm::vec3& position, AmbientType type);
void removeEmitter(uint64_t id);
void clearEmitters();
// Time of day control (0-24 hours)
void setGameTime(float hours);
// Volume control
void setVolumeScale(float scale);
private:
struct AmbientEmitter {
uint64_t id;
AmbientType type;
glm::vec3 position;
bool active;
float lastPlayTime;
float loopInterval; // For periodic/looping sounds
};
struct AmbientSample {
std::string path;
std::vector<uint8_t> data;
bool loaded;
};
// Sound libraries
std::vector<AmbientSample> fireSoundsSmall_;
std::vector<AmbientSample> fireSoundsLarge_;
std::vector<AmbientSample> torchSounds_;
std::vector<AmbientSample> waterSounds_;
std::vector<AmbientSample> riverSounds_;
std::vector<AmbientSample> waterfallSounds_;
std::vector<AmbientSample> windSounds_;
std::vector<AmbientSample> tavernSounds_;
// Active emitters
std::vector<AmbientEmitter> emitters_;
uint64_t nextEmitterId_ = 1;
// State tracking
float gameTimeHours_ = 12.0f; // Default noon
float volumeScale_ = 1.0f;
float birdTimer_ = 0.0f;
float cricketTimer_ = 0.0f;
float windLoopTime_ = 0.0f;
bool wasIndoor_ = false;
bool initialized_ = false;
// Active audio tracking
struct ActiveSound {
uint64_t emitterId;
float startTime;
};
std::vector<ActiveSound> activeSounds_;
// Helper methods
void updatePositionalEmitters(float deltaTime, const glm::vec3& cameraPos);
void updatePeriodicSounds(float deltaTime, bool isIndoor, bool isSwimming);
void updateWindAmbience(float deltaTime, bool isIndoor);
bool loadSound(const std::string& path, AmbientSample& sample, pipeline::AssetManager* assets);
// Time of day helpers
bool isDaytime() const { return gameTimeHours_ >= 6.0f && gameTimeHours_ < 20.0f; }
bool isNighttime() const { return !isDaytime(); }
};
} // namespace audio
} // namespace wowee

View file

@ -22,6 +22,7 @@ public:
void update(float deltaTime);
void setVolume(int volume);
int getVolume() const { return volumePercent; }
void setUnderwaterMode(bool underwater);
bool isPlaying() const { return playing; }
bool isInitialized() const { return assetManager != nullptr; }
@ -33,6 +34,7 @@ private:
bool currentTrackIsFile = false;
bool playing = false;
int volumePercent = 30;
bool underwaterMode = false;
// Crossfade state
bool crossfading = false;

View file

@ -62,7 +62,7 @@ private:
return oss.str();
}
LogLevel minLevel = LogLevel::DEBUG;
LogLevel minLevel = LogLevel::INFO; // Changed from DEBUG to reduce log spam
std::mutex mutex;
std::ofstream fileStream;
bool fileReady = false;

View file

@ -8,7 +8,7 @@
namespace wowee {
namespace core { class Window; }
namespace game { class World; class ZoneManager; }
namespace audio { class MusicManager; class FootstepManager; class ActivitySoundManager; class MountSoundManager; class NpcVoiceManager; enum class FootstepSurface : uint8_t; enum class VoiceType; }
namespace audio { class MusicManager; class FootstepManager; class ActivitySoundManager; class MountSoundManager; class NpcVoiceManager; class AmbientSoundManager; enum class FootstepSurface : uint8_t; enum class VoiceType; }
namespace pipeline { class AssetManager; }
namespace rendering {
@ -150,6 +150,7 @@ public:
audio::ActivitySoundManager* getActivitySoundManager() { return activitySoundManager.get(); }
audio::MountSoundManager* getMountSoundManager() { return mountSoundManager.get(); }
audio::NpcVoiceManager* getNpcVoiceManager() { return npcVoiceManager.get(); }
audio::AmbientSoundManager* getAmbientSoundManager() { return ambientSoundManager.get(); }
private:
core::Window* window = nullptr;
@ -177,6 +178,7 @@ private:
std::unique_ptr<audio::ActivitySoundManager> activitySoundManager;
std::unique_ptr<audio::MountSoundManager> mountSoundManager;
std::unique_ptr<audio::NpcVoiceManager> npcVoiceManager;
std::unique_ptr<audio::AmbientSoundManager> ambientSoundManager;
std::unique_ptr<game::ZoneManager> zoneManager;
std::unique_ptr<Shader> underwaterOverlayShader;
uint32_t underwaterOverlayVAO = 0;

View file

@ -22,6 +22,7 @@
namespace wowee {
namespace pipeline { class AssetManager; }
namespace audio { class AmbientSoundManager; }
namespace rendering { class TerrainRenderer; class Camera; class WaterRenderer; class M2Renderer; class WMORenderer; }
namespace rendering {
@ -106,6 +107,13 @@ struct PendingTile {
};
std::vector<WMODoodadReady> wmoDoodads;
// Ambient sound emitters (detected from doodads)
struct AmbientEmitter {
glm::vec3 position;
uint32_t type; // Maps to AmbientSoundManager::AmbientType
};
std::vector<AmbientEmitter> ambientEmitters;
// Pre-loaded terrain texture BLP data (loaded on background thread to avoid
// blocking file I/O on the main thread during finalizeTile)
std::unordered_map<std::string, pipeline::BLPImage> preloadedTextures;
@ -182,6 +190,7 @@ public:
void setWaterRenderer(WaterRenderer* renderer) { waterRenderer = renderer; }
void setM2Renderer(M2Renderer* renderer) { m2Renderer = renderer; }
void setWMORenderer(WMORenderer* renderer) { wmoRenderer = renderer; }
void setAmbientSoundManager(audio::AmbientSoundManager* manager) { ambientSoundManager = manager; }
/**
* Get terrain height at GL coordinates
@ -257,6 +266,7 @@ private:
WaterRenderer* waterRenderer = nullptr;
M2Renderer* m2Renderer = nullptr;
WMORenderer* wmoRenderer = nullptr;
audio::AmbientSoundManager* ambientSoundManager = nullptr;
std::string mapName = "Azeroth";