mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-10 02:53:51 +00:00
feat(pipeline): add WSND (Wowee Sound Catalog) format
Novel open replacement for Blizzard's SoundEntries.dbc +
SoundEntriesAdvanced.dbc. The 10th open format added to the
editor — covers the audio-metadata gap (the previous 9 cover
geometry, terrain, atmosphere, and world manifests, but no
sound metadata).
Format:
• magic "WSND", version 1, little-endian
• catalogName + entry count
• per entry: soundId / kind / flags / volume /
minDistance / maxDistance / filePath / label
Kind enum (7 categories):
sfx, music, ambient, ui, voice, spell, combat
Flags packed (3 bits used, rest reserved):
loop (0x01), 3d (0x02), stream (0x04)
API: WoweeSoundLoader::save / load / exists; presets
makeStarter (one entry per kind), makeAmbient (wilderness
loops + footsteps), makeTavern (fire + crowd + drink + door
+ lute).
CLI added (5 flags, 465 documented total now):
--gen-sound-catalog <base> [name]
--gen-sound-catalog-ambient <base> [name]
--gen-sound-catalog-tavern <base> [name]
--info-wsnd <base> [--json]
--validate-wsnd <base> [--json]
Validator catches: out-of-range kind, NaN/inf volume or
distances, 3D sounds with bad min/max, duplicate sound IDs,
empty filePaths.
All 3 presets verified: save / load / validate clean
on first run. Variable-length string fields use length-
prefixed encoding with a 1 MiB sanity cap on read to
prevent corrupted-file allocation blowups.
This commit is contained in:
parent
13312096ea
commit
36d63d8dd0
8 changed files with 566 additions and 0 deletions
100
include/pipeline/wowee_sound.hpp
Normal file
100
include/pipeline/wowee_sound.hpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline {
|
||||
|
||||
// Wowee Open Sound Catalog (.wsnd) — novel replacement for
|
||||
// Blizzard's SoundEntries.dbc + SoundEntriesAdvanced.dbc.
|
||||
// One file holds all sound metadata for a zone or feature: UI
|
||||
// clicks, ambient loops, spell SFX, voice clips, combat hits.
|
||||
// The runtime keys lookups by soundId; the catalog name is
|
||||
// just a label for debugging / tooling.
|
||||
//
|
||||
// 3D positional sounds are described by minDistance (the
|
||||
// radius within which the sound plays at full volume) and
|
||||
// maxDistance (beyond which it is fully attenuated). Loop
|
||||
// flag, stream flag, and 3D flag are packed into the flags
|
||||
// field so a future format extension can reuse other bits.
|
||||
//
|
||||
// Binary layout (little-endian):
|
||||
// magic[4] = "WSND"
|
||||
// version (uint32) = current 1
|
||||
// nameLen (uint32) + name bytes -- catalog label
|
||||
// entryCount (uint32)
|
||||
// entries (each):
|
||||
// soundId (uint32)
|
||||
// kind (uint8)
|
||||
// pad[3]
|
||||
// flags (uint32)
|
||||
// volume (float)
|
||||
// minDistance (float)
|
||||
// maxDistance (float)
|
||||
// filePathLen (uint32) + filePath bytes
|
||||
// labelLen (uint32) + label bytes
|
||||
struct WoweeSound {
|
||||
enum Kind : uint8_t {
|
||||
Sfx = 0,
|
||||
Music = 1,
|
||||
Ambient = 2,
|
||||
Ui = 3,
|
||||
Voice = 4,
|
||||
Spell = 5,
|
||||
Combat = 6,
|
||||
};
|
||||
|
||||
enum Flags : uint32_t {
|
||||
Loop = 0x01,
|
||||
Is3D = 0x02,
|
||||
Stream = 0x04,
|
||||
};
|
||||
|
||||
struct Entry {
|
||||
uint32_t soundId = 0;
|
||||
uint8_t kind = Sfx;
|
||||
uint32_t flags = 0;
|
||||
float volume = 1.0f;
|
||||
float minDistance = 5.0f;
|
||||
float maxDistance = 30.0f;
|
||||
std::string filePath;
|
||||
std::string label;
|
||||
};
|
||||
|
||||
std::string name;
|
||||
std::vector<Entry> entries;
|
||||
|
||||
bool isValid() const { return !entries.empty(); }
|
||||
|
||||
// Lookup by soundId — returns nullptr if not present.
|
||||
const Entry* findById(uint32_t soundId) const;
|
||||
|
||||
static const char* kindName(uint8_t k);
|
||||
};
|
||||
|
||||
class WoweeSoundLoader {
|
||||
public:
|
||||
static bool save(const WoweeSound& cat,
|
||||
const std::string& basePath);
|
||||
static WoweeSound load(const std::string& basePath);
|
||||
static bool exists(const std::string& basePath);
|
||||
|
||||
// Preset emitters used by --gen-sound-catalog* variants.
|
||||
//
|
||||
// makeStarter — one entry per kind covering the common
|
||||
// sound categories (sfx / music / ambient
|
||||
// / ui / voice / spell / combat). Useful
|
||||
// as a template for hand-edit.
|
||||
// makeAmbient — wilderness-style: bird-loop ambient +
|
||||
// wind ambient + footstep variants.
|
||||
// makeTavern — interior: crackling-fire ambient + crowd
|
||||
// murmur + drink-clink + door-creak.
|
||||
static WoweeSound makeStarter(const std::string& catalogName);
|
||||
static WoweeSound makeAmbient(const std::string& catalogName);
|
||||
static WoweeSound makeTavern(const std::string& catalogName);
|
||||
};
|
||||
|
||||
} // namespace pipeline
|
||||
} // namespace wowee
|
||||
Loading…
Add table
Add a link
Reference in a new issue