Skip to content

Commit

Permalink
sndpp: create WAV, XWV parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
craftablescience committed Feb 2, 2025
1 parent b2d8b85 commit 3328227
Show file tree
Hide file tree
Showing 10 changed files with 784 additions and 3 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ option(SOURCEPP_USE_FSPP "Build fspp library" ${SOURC
option(SOURCEPP_USE_GAMEPP "Build gamepp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_KVPP "Build kvpp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_MDLPP "Build mdlpp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_SNDPP "Build sndpp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_STEAMPP "Build steampp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_TOOLPP "Build toolpp library" ${SOURCEPP_LIBS_START_ENABLED})
option(SOURCEPP_USE_VCRYPTPP "Build vcryptpp library" ${SOURCEPP_LIBS_START_ENABLED})
Expand Down Expand Up @@ -203,6 +204,7 @@ add_sourcepp_library(fspp ) # sourcepp::fspp
add_sourcepp_library(gamepp C PYTHON ) # sourcepp::gamepp
add_sourcepp_library(kvpp BENCH) # sourcepp::kvpp
add_sourcepp_library(mdlpp ) # sourcepp::mdlpp
add_sourcepp_library(sndpp ) # sourcepp::sndpp
add_sourcepp_library(steampp C PYTHON ) # sourcepp::steampp
add_sourcepp_library(toolpp PYTHON ) # sourcepp::toolpp
add_sourcepp_library(vcryptpp C CSHARP PYTHON ) # sourcepp::vcryptpp
Expand Down Expand Up @@ -270,7 +272,7 @@ endif()

# Print options
print_options(OPTIONS
USE_BSPPP USE_DMXPP USE_FSPP USE_GAMEPP USE_KVPP USE_MDLPP USE_STEAMPP USE_TOOLPP USE_VCRYPTPP USE_VPKPP USE_VTFPP
USE_BSPPP USE_DMXPP USE_FSPP USE_GAMEPP USE_KVPP USE_MDLPP USE_SNDPP USE_STEAMPP USE_TOOLPP USE_VCRYPTPP USE_VPKPP USE_VTFPP
BUILD_BENCHMARKS BUILD_C_WRAPPERS BUILD_CSHARP_WRAPPERS BUILD_PYTHON_WRAPPERS BUILD_WITH_OPENCL BUILD_WITH_TBB BUILD_WITH_THREADS BUILD_TESTS BUILD_WIN7_COMPAT
LINK_STATIC_MSVC_RUNTIME
VPKPP_SUPPORT_VPK_V54)
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
<tr><!-- empty row to disable github striped bg color --></tr>
<tr>
<td rowspan="1"><code>fspp</code><sup>*</sup></td>
<td>(WIP) Source 1 filesystem accessor</td>
<td>Source 1 filesystem accessor</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td rowspan="1" align="center"></td>
Expand Down Expand Up @@ -92,6 +92,20 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
<td align="center">❌</td>
</tr>
<tr><!-- empty row to disable github striped bg color --></tr>
<tr>
<td rowspan="3"><code>sndpp</code><sup>*</sup></td>
<td>WAV</td>
<td align="center">✅</td>
<td align="center">❌</td>
<td rowspan="3" align="center"></td>
</tr>
<tr><!-- empty row to disable github striped bg color --></tr>
<tr>
<td>XWV v4</td>
<td align="center">✅</td>
<td align="center">❌</td>
</tr>
<tr><!-- empty row to disable github striped bg color --></tr>
<tr>
<td rowspan="3"><code>steampp</code></td>
<td>Find Steam install folder</td>
Expand Down
14 changes: 13 additions & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
</tr>
<tr>
<td rowspan="1"><code>fspp</code><sup>*</sup></td>
<td>(WIP) Source 1 filesystem accessor</td>
<td>Source 1 filesystem accessor</td>
<td align="center">✅</td>
<td align="center">✅</td>
<td rowspan="1" align="center"></td>
Expand Down Expand Up @@ -83,6 +83,18 @@ Several modern C++20 libraries for sanely parsing Valve formats, rolled into one
<td align="center">✅</td>
<td align="center">❌</td>
</tr>
<tr>
<td rowspan="2"><code>sndpp</code><sup>*</sup></td>
<td>WAV</td>
<td align="center">✅</td>
<td align="center">❌</td>
<td rowspan="2" align="center"></td>
</tr>
<tr>
<td>XWV v4</td>
<td align="center">✅</td>
<td align="center">❌</td>
</tr>
<tr>
<td rowspan="2"><code>steampp</code></td>
<td>Find Steam install folder</td>
Expand Down
260 changes: 260 additions & 0 deletions include/sndpp/WAV.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
#pragma once

#include <array>
#include <cstddef>
#include <memory>
#include <span>
#include <string>
#include <vector>

#include <sourcepp/parser/Binary.h>

namespace sndpp {

constexpr auto RIFF_SIGNATURE = sourcepp::parser::binary::makeFourCC("RIFF");
constexpr auto RIFX_SIGNATURE = sourcepp::parser::binary::makeFourCC("RIFX");
constexpr auto FFIR_SIGNATURE = sourcepp::parser::binary::makeFourCC("FFIR");

class WAV {
public:
static constexpr auto RIFF_TYPE = sourcepp::parser::binary::makeFourCC("WAVE");

enum class ChunkType : uint32_t {
FMT = sourcepp::parser::binary::makeFourCC("fmt "), // Track details
DATA = sourcepp::parser::binary::makeFourCC("data"), // The audio data
CUE = sourcepp::parser::binary::makeFourCC("cue "), // Cue points / markers
PLST = sourcepp::parser::binary::makeFourCC("plst"), // Playlist for cue points
FACT = sourcepp::parser::binary::makeFourCC("fact"), // More track details
SMPL = sourcepp::parser::binary::makeFourCC("smpl"), // Sampler
INST = sourcepp::parser::binary::makeFourCC("inst"), // Instrument
CSET = sourcepp::parser::binary::makeFourCC("CSET"), // Character set
MD5 = sourcepp::parser::binary::makeFourCC("MD5 "), // Checksums
JUNK = sourcepp::parser::binary::makeFourCC("JUNK"), // Useless
PAD = sourcepp::parser::binary::makeFourCC("PAD "), // Useless
FLLR = sourcepp::parser::binary::makeFourCC("FLLR"), // Useless
LIST = sourcepp::parser::binary::makeFourCC("LIST"), // Metadata
};

enum class ChunkListType : uint32_t {
WAVL = sourcepp::parser::binary::makeFourCC("WAVL"), // Wave list
INFO = sourcepp::parser::binary::makeFourCC("INFO"), // Overall metadata
ADTL = sourcepp::parser::binary::makeFourCC("adtl"), // Cue points metadata
};

enum class ChunkListInfoType : uint32_t {
IARL = sourcepp::parser::binary::makeFourCC("IARL"), // Archive location
IGNR = sourcepp::parser::binary::makeFourCC("IGNR"), // Genre
IKEY = sourcepp::parser::binary::makeFourCC("IKEY"), // Keywords
ILGT = sourcepp::parser::binary::makeFourCC("ILGT"), // Lightness
IMED = sourcepp::parser::binary::makeFourCC("IMED"), // Medium
INAM = sourcepp::parser::binary::makeFourCC("INAM"), // Title
IPLT = sourcepp::parser::binary::makeFourCC("IPLT"), // Palatte setting
IPRD = sourcepp::parser::binary::makeFourCC("IPRD"), // Product
ISBJ = sourcepp::parser::binary::makeFourCC("ISBJ"), // Subject
ISFT = sourcepp::parser::binary::makeFourCC("ISFT"), // Software used
ISHP = sourcepp::parser::binary::makeFourCC("ISHP"), // Sharpness
IART = sourcepp::parser::binary::makeFourCC("IART"), // Artist
ISRC = sourcepp::parser::binary::makeFourCC("ISRC"), // Source (file supplier)
ISRF = sourcepp::parser::binary::makeFourCC("ISRF"), // Source form
ITCH = sourcepp::parser::binary::makeFourCC("ITCH"), // Technician
ICMS = sourcepp::parser::binary::makeFourCC("ICMS"), // Commissioner
ICMT = sourcepp::parser::binary::makeFourCC("ICMT"), // Comments
ICOP = sourcepp::parser::binary::makeFourCC("ICOP"), // Copyright
ICRP = sourcepp::parser::binary::makeFourCC("ICRP"), // Crop
IDPI = sourcepp::parser::binary::makeFourCC("IDPI"), // Dots per inch
IENG = sourcepp::parser::binary::makeFourCC("IENG"), // Engineer
ISMP = sourcepp::parser::binary::makeFourCC("ISMP"), // Digitization start time (SMPTE time code)
IDIT = sourcepp::parser::binary::makeFourCC("IDIT"), // Digitization start time (26 characters, formatted like "Wed Jan 02 02:03:55 1990\n\0")
ICRD = sourcepp::parser::binary::makeFourCC("ICRD"), // Creation date (YYYY, YYYY-MM, YYYY-MM-DD)
ITRK = sourcepp::parser::binary::makeFourCC("ITRK"), // Track number
};

enum class ChunkListADTLType {
LABL = sourcepp::parser::binary::makeFourCC("labl"), // Cue point label
NOTE = sourcepp::parser::binary::makeFourCC("note"), // Cue point note
LTXT = sourcepp::parser::binary::makeFourCC("ltxt"), // Section label
};

struct ChunkBase {
virtual ~ChunkBase() = default;

ChunkType type = ChunkType::JUNK;
};

struct ChunkFMT : ChunkBase {
uint16_t format;
uint16_t channels;
uint32_t samplesPerSecond;
uint32_t averageBytesPerSecond;
uint16_t blockAlign;
uint16_t bitsPerSample;
std::vector<std::byte> extraCompressionInfo;
};

struct ChunkDATA : ChunkBase {
std::vector<std::byte> data;
};

struct ChunkCUE : ChunkBase {
struct CuePoint {
uint32_t id;
int32_t position;
ChunkType chunk;
uint32_t chunkStart;
uint32_t blockStart;
uint32_t sampleOffset;
};

std::vector<CuePoint> cuePoints;
};

struct ChunkPLST : ChunkBase {
struct Segment {
uint32_t id;
uint32_t length;
uint32_t repeats;
};

std::vector<Segment> segments;
};

struct ChunkFACT : ChunkBase {
uint32_t samples;
std::vector<std::byte> extraCompressionInfo;
};

struct ChunkSMPL : ChunkBase {
struct SampleLoop {
uint32_t id;
uint32_t type;
uint32_t start;
uint32_t end;
uint32_t fraction;
uint32_t playCount;
};

uint32_t manufacturer;
uint32_t product;
uint32_t samplePeriod;
uint32_t midiUnityNote;
uint32_t midiPitchFraction;
uint32_t smpteFormat;
uint32_t smpteOffset;
uint32_t sampleLoops;
uint32_t samplerData;
std::vector<SampleLoop> loops;
};

struct ChunkINST : ChunkBase {
uint8_t unshiftedNote;
int8_t fineTune;
int8_t gain;
uint8_t lowNote;
uint8_t highNote;
uint8_t lowVelocity;
uint8_t highVelocity;
};

struct ChunkCSET : ChunkBase {
uint16_t codePage;
uint16_t countryCode;
uint16_t language;
uint16_t dialect;
};

struct ChunkMD5 : ChunkBase {
std::array<uint8_t, 16> md5;
};

struct ChunkJUNK : ChunkBase {
std::vector<std::byte> junk;
};

struct ChunkPAD : ChunkBase {
std::vector<std::byte> padding;
};

struct ChunkFLLR : ChunkBase {
std::vector<std::byte> filler;
};

struct ChunkLIST : ChunkBase {};

struct ChunkINFO : ChunkLIST {
struct META {
ChunkListInfoType type;
std::string metadata;
};

std::vector<META> metadata;
};

struct ChunkADTL : ChunkLIST {
struct LABL {
uint32_t id;
std::string label;
};

struct NOTE {
uint32_t id;
std::string note;
};

struct LTXT {
uint32_t id;
uint32_t sampleLength;
uint32_t purpose;
uint16_t country;
uint16_t language;
uint16_t dialect;
uint16_t codePage;
std::string label;
};

std::vector<LABL> labels;
std::vector<NOTE> notes;
std::vector<LTXT> labelTexts;
};

struct ChunkUnknown : ChunkBase {
std::vector<std::byte> data;
};

WAV();

explicit WAV(std::span<const std::byte> wavData);

explicit WAV(const std::string& wavPath);

[[nodiscard]] explicit operator bool() const;

[[nodiscard]] const std::vector<std::unique_ptr<ChunkBase>>& getChunks() const;

[[nodiscard]] std::vector<std::unique_ptr<ChunkBase>>& getChunks();

[[nodiscard]] const ChunkBase* getFirstChunk(WAV::ChunkType type) const;

[[nodiscard]] const ChunkFMT* getChunkFMT() const;
[[nodiscard]] const ChunkDATA* getChunkDATA() const;
[[nodiscard]] const ChunkCUE* getChunkCUE() const;
[[nodiscard]] const ChunkPLST* getChunkPLST() const;
[[nodiscard]] const ChunkFACT* getChunkFACT() const;
[[nodiscard]] const ChunkSMPL* getChunkSMPL() const;
[[nodiscard]] const ChunkINST* getChunkINST() const;
[[nodiscard]] const ChunkCSET* getChunkCSET() const;
[[nodiscard]] const ChunkMD5* getChunkMD5() const;
[[nodiscard]] const ChunkJUNK* getChunkJUNK() const;
[[nodiscard]] const ChunkPAD* getChunkPAD() const;
[[nodiscard]] const ChunkFLLR* getChunkFLLR() const;
[[nodiscard]] const ChunkLIST* getChunkLIST() const;

[[nodiscard]] uint32_t getSignature() const;

void setSignature(uint32_t newSignature);

protected:
std::vector<std::unique_ptr<ChunkBase>> chunks;
uint32_t signature;
};

} // namespace sndpp
Loading

0 comments on commit 3328227

Please sign in to comment.