Ψ-W2-T2: collapse a capture whose channels are bit-identical to one lossless mono channel, index value measured off the landed file
This commit is contained in:
@@ -257,6 +257,44 @@ std::vector<std::uint8_t> buildFloat32Wav(int nch, std::uint32_t rate,
|
||||
return out;
|
||||
}
|
||||
|
||||
MonoCollapse collapseToMono(const std::vector<std::uint8_t>& bytes) {
|
||||
MonoCollapse out;
|
||||
|
||||
const WavLayout layout = parseWavLayout(bytes);
|
||||
if (!layout.valid || layout.channelCount < 2) return out;
|
||||
|
||||
const std::size_t frames = layout.frameCount();
|
||||
if (frames == 0) return out;
|
||||
|
||||
const std::size_t stride = layout.channelCount;
|
||||
const std::vector<AudioSample> pcm = extractFloatFrames(bytes, layout, 0, frames);
|
||||
if (pcm.size() != frames * stride) return out; // short read -> decline, never guess
|
||||
|
||||
// Bit patterns, not values: see the header. memcpy is the only defined float->bits
|
||||
// read, and it compiles to a register move.
|
||||
auto bitsOf = [](AudioSample s) {
|
||||
std::uint32_t bits = 0;
|
||||
std::memcpy(&bits, &s, 4u);
|
||||
return bits;
|
||||
};
|
||||
for (std::size_t f = 0; f < frames; ++f) {
|
||||
const std::uint32_t first = bitsOf(pcm[f * stride]);
|
||||
for (std::size_t c = 1; c < stride; ++c) {
|
||||
if (bitsOf(pcm[f * stride + c]) != first) return out;
|
||||
}
|
||||
}
|
||||
|
||||
// float -> double -> float round-trips exactly (double represents every float),
|
||||
// so channel 0 reaches the rebuilt file unaltered.
|
||||
std::vector<double> mono(frames);
|
||||
for (std::size_t f = 0; f < frames; ++f)
|
||||
mono[f] = static_cast<double>(pcm[f * stride]);
|
||||
|
||||
out.collapsed = true;
|
||||
out.bytes = buildFloat32Wav(1, layout.sampleRate, frames, mono);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string hashBytes(const std::uint8_t* data, std::size_t len) {
|
||||
// FNV-1a 64-bit: deterministic, no dependencies, adequate for dedup identity.
|
||||
std::uint64_t h = kFnvOffsetBasis;
|
||||
|
||||
Reference in New Issue
Block a user