Sound Archives (.snd)

Sound archives store DOOM: Eternal and DOOM: The Dark Ages audio files (samples).

File Format

// Eternal version of sndEntry

struct sndEntry_Eternal

{

	uint64_t farmhash; // Farmhash64 of the entry's DECODED data

 uint32_t sampleID; // ID used to to reference this sample in the sound banks

 uint32_t encodedSize; // Size of the entry's data as it's stored in the archive.

 uint64_t offset; // Location of entry's data in the file. Relative to beginning of file

 uint32_t decodedSize; // Size of the entry's data after being decoded

 uint16_t encoding; // Either 2 or 3

 uint16_t metaSize; // Size of this entry's meta section inside the meta blob

 uint32_t metaOffset; // Location of this entry's meta section. Relative to global offset 0xC

}

// Dark Ages version of sndEntry

struct sndEntry_DarkAges

{

	uint64_t farmhash; // Farmhash64 of the entry's data

 uint32_t sampleID; // ID used to to reference this sample in the sound banks

 uint32_t encodedSize; // Size of the entry's data as it's stored in the archive.

 uint64_t offset; // Location of entry's data in the file. Relative to beginning of file

 uint32_t decodedSize; // Always equal to encodedSize

 uint32_t metaSize; // Size of this entry's meta section inside the meta blob

 uint32_t metaOffset; // Location of this entry's meta section. Relative to global offset 0xC

}

struct sndHeaderChunk

{

	uint32_t metaSize; // Size of the header chunk's meta blob + 4

 char* metaBlob; // Header chunk's meta blob. Length == metaSize - 4

 uint32_t numEntries; // Number of entries

	sndEntry* entries; // Array of entry information. Length == numEntries. Exact format depends on the game 

}

struct snd

{

	uint32_t version; // Always 6

 uint32_t headerSize; // Size of the header chunk

 sndHeaderChunk; // Header chunk. Exact size given by headerSize

 char* dataChunk; // Data chunk. Stores the complete audio samples. Length == remainder of file

}

About: Meta Blob

Audio samples in both games use RIFF as their basic format. A sample's "meta" section consists of the start of the file, up to and including the length field of it's data chunk.

Code that demonstrates how to calculate the length of a sample's meta chunk can be found here