Q-W2v: split VST god-modules — editor 8 face-axis TUs (+pure layout hoist), processor 3 TUs, component_state_io codec split (extension drops the voice engine), zone_params.h, core/wire putLE; formats frozen, 61/61 green

This commit is contained in:
2026-07-29 10:56:09 -04:00
parent 9d5783453c
commit ea86f540b8
37 changed files with 6202 additions and 5352 deletions
+110
View File
@@ -0,0 +1,110 @@
// core/wire/bytes.h — the ONE little-endian byte codec (Q-W2v; audit T4-20).
// Pure, header-only: standard library only — NO REAPER, NO SWELL, NO VST3.
//
// Five hand-rolled LE copies existed at the Q-W0 census (sample_map's
// putU32le/putU64le + ByteReader, capture_realtime's writeU32LE, capture_paths'
// readU32LE lambda, ingest's putU32 lambda, instrument_drop's appendU32LE). This
// template is the single survivor: compile-time dispatched, zero runtime cost,
// entirely off hot paths (serialization / file I/O only). The ComponentState
// codec (component_state_io) is its biggest consumer; the remaining hand-rolled
// copies rewire opportunistically in the waves that already open their files.
//
// Wire formats are FROZEN: putLE<u32>/putLE<u64> emit exactly the bytes the
// retired putU32le/putU64le emitted (LSB first, fixed width), and ByteReader
// preserves the latch-on-truncation contract (once a read runs past the end,
// ok latches false and every subsequent read yields zeros/empties — a truncated
// blob degrades to a partial parse, never out-of-bounds).
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <string>
#include <type_traits>
#include <vector>
namespace reasampler::wire {
// Append `v` little-endian (LSB first, sizeof(T) bytes). Unsigned integral types
// only — signed values go on the wire as their two's-complement unsigned image
// (cast at the call site, the established idiom: u32 for int, u64 for int64).
template <class T>
inline void putLE(std::vector<std::uint8_t>& out, T v) {
static_assert(std::is_unsigned_v<T>, "putLE takes the unsigned wire image");
for (std::size_t b = 0; b < sizeof(T); ++b) {
out.push_back(static_cast<std::uint8_t>((v >> (b * 8)) & 0xFF));
}
}
// IEEE-754 double <-> u64 bit-cast for the wire (memcpy is the only defined
// type-pun in C++17). Doubles ride the wire as their u64 bit image via putLE.
inline std::uint64_t doubleToBits(double d) {
std::uint64_t bits;
std::memcpy(&bits, &d, sizeof(bits));
return bits;
}
inline double bitsToDouble(std::uint64_t bits) {
double d;
std::memcpy(&d, &bits, sizeof(d));
return d;
}
// A bounded little-endian reader over a byte blob. Every read is length-checked;
// once a read runs past the end the reader latches `ok=false` and yields zeros,
// so a truncated blob degrades to a partial/empty parse rather than reading out
// of bounds. (The class formerly private to sample_map.cpp, promoted here as the
// codec's tested primitive — T4-20.)
struct ByteReader {
const std::vector<std::uint8_t>& bytes;
std::size_t pos = 0;
bool ok = true;
explicit ByteReader(const std::vector<std::uint8_t>& b) : bytes(b) {}
// Read one unsigned integral little-endian (fixed sizeof(T) width).
template <class T>
T readLE() {
static_assert(std::is_unsigned_v<T>, "readLE yields the unsigned wire image");
if (!ok || pos + sizeof(T) > bytes.size()) {
ok = false;
return 0;
}
T v = 0;
for (std::size_t b = 0; b < sizeof(T); ++b) {
v |= static_cast<T>(bytes[pos + b]) << (b * 8);
}
pos += sizeof(T);
return v;
}
std::uint8_t u8() { return readLE<std::uint8_t>(); }
std::uint32_t u32() { return readLE<std::uint32_t>(); }
std::uint64_t u64() { return readLE<std::uint64_t>(); }
// Signed ints ride the wire as fixed-width two's-complement unsigned images.
int i32() { return static_cast<int>(static_cast<std::int32_t>(u32())); }
std::int64_t i64() { return static_cast<std::int64_t>(u64()); }
std::string str(std::uint32_t len) {
if (!ok || pos + len > bytes.size()) {
ok = false;
return {};
}
std::string s(reinterpret_cast<const char*>(bytes.data() + pos), len);
pos += len;
return s;
}
// Non-consuming peek of the next u32 (format-marker probes). Yields 0 and
// latches nothing when fewer than 4 bytes remain — the caller treats a short
// blob as "no marker" and falls through to its (also-guarded) fallback read.
std::uint32_t peekU32() const {
if (!ok || pos + 4 > bytes.size()) return 0;
return static_cast<std::uint32_t>(bytes[pos]) |
(static_cast<std::uint32_t>(bytes[pos + 1]) << 8) |
(static_cast<std::uint32_t>(bytes[pos + 2]) << 16) |
(static_cast<std::uint32_t>(bytes[pos + 3]) << 24);
}
};
} // namespace reasampler::wire
+13 -19
View File
@@ -7,25 +7,19 @@
#include <cstdio>
#include "core/wire/reasampler_uid.h" // REASAMPLER_ACTIVE_UID_* — the FROZEN, channel-selected class UID
#include "core/instrument/map/sample_map.h" // ComponentState + serializeComponentState (the SHARED writer)
#include "core/instrument/map/component_state_io.h" // ComponentState + serializeComponentState (the SHARED writer, Q-W2v codec split)
#include "core/wire/bytes.h" // putLE — the ONE LE byte codec (T4-20)
namespace reasampler::wire {
using instrument::map::ComponentState;
using instrument::map::serializeComponentState;
namespace {
// Little-endian appenders — the .vstpreset container stores its integers little-endian on
// disk (public.sdk vstpresetfile.cpp swaps only on big-endian hosts).
void appendU32LE(std::vector<std::uint8_t>& out, std::uint32_t v) {
out.push_back(static_cast<std::uint8_t>(v & 0xFF));
out.push_back(static_cast<std::uint8_t>((v >> 8) & 0xFF));
out.push_back(static_cast<std::uint8_t>((v >> 16) & 0xFF));
out.push_back(static_cast<std::uint8_t>((v >> 24) & 0xFF));
}
void appendU64LE(std::vector<std::uint8_t>& out, std::uint64_t v) {
for (int i = 0; i < 8; ++i)
out.push_back(static_cast<std::uint8_t>((v >> (8 * i)) & 0xFF));
}
// The .vstpreset container stores its integers little-endian on disk (public.sdk
// vstpresetfile.cpp swaps only on big-endian hosts) — putLE (core/wire/bytes.h) is
// exactly that byte order; the former appendU32LE/appendU64LE copies are retired (T4-20).
void appendFourCC(std::vector<std::uint8_t>& out, const char id[4]) {
out.insert(out.end(), id, id + 4);
@@ -58,19 +52,19 @@ std::vector<std::uint8_t> buildVstPresetBytes(
out.reserve(static_cast<std::size_t>(listOffset) + 4 + 4 + (4 + 8 + 8));
appendFourCC(out, "VST3");
appendU32LE(out, 1); // kFormatVersion
putLE<std::uint32_t>(out, 1); // kFormatVersion
out.insert(out.end(), classIdHex32.begin(), classIdHex32.end());
appendU64LE(out, listOffset);
putLE<std::uint64_t>(out, listOffset);
// Data area: the one 'Comp' chunk's bytes, at offset kHeaderSize.
out.insert(out.end(), componentState.begin(), componentState.end());
// Chunk list: 'List' + entry count + one entry {'Comp', offset, size}.
appendFourCC(out, "List");
appendU32LE(out, 1);
putLE<std::uint32_t>(out, 1);
appendFourCC(out, "Comp");
appendU64LE(out, kHeaderSize);
appendU64LE(out, compSize);
putLE<std::uint64_t>(out, kHeaderSize);
putLE<std::uint64_t>(out, compSize);
return out;
}