Clean up common/ comments and the log-ring strncpy warning
Comments must not document the past or reference plan circumstances: drop the stale pointer to a never-created audio_correlate_layout.hpp, the "step b" plan labels, the "carved out of reserved space" history note, and a README pointer; reword a past-tense seqlock comment to describe the failure mode in the present. Replace the strncpy in log_ring_push with a bounded memcpy: same semantics (truncate + NUL), but without the C4996 deprecation warning on every host build.
This commit is contained in:
@@ -15,8 +15,8 @@
|
|||||||
//
|
//
|
||||||
// This header is the pure, headless-testable core (no devices, no WASAPI). The host downmixes the
|
// This header is the pure, headless-testable core (no devices, no WASAPI). The host downmixes the
|
||||||
// two captures to mono float, calls correlate_rate(), and feeds the result into the existing rate
|
// two captures to mono float, calls correlate_rate(), and feeds the result into the existing rate
|
||||||
// path (publish / override). audio_correlate_layout.hpp (step b) reuses these helpers to also
|
// path (publish / override). correlate_format() below builds on the same helpers to also recover
|
||||||
// recover channels + bit depth by trying candidate de-interleavings.
|
// channels + bit depth by trying candidate de-interleavings.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@@ -254,7 +254,7 @@ inline RateCorrelation correlate_rate(const std::vector<float>& hook_mono, const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Step (b): channels + bit-depth recovery --------------------------------------------------
|
// --- Channels + bit-depth recovery -------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// The rate step assumes the hook bytes are de-interleaved at the device channel/bit layout. When a
|
// The rate step assumes the hook bytes are de-interleaved at the device channel/bit layout. When a
|
||||||
// game renders a DIFFERENT layout than the device (e.g. stereo float on a 7.1 endpoint, or 16-bit
|
// game renders a DIFFERENT layout than the device (e.g. stereo float on a 7.1 endpoint, or 16-bit
|
||||||
|
|||||||
@@ -90,10 +90,9 @@ struct AudioRingHeader
|
|||||||
// Host -> hook: format-verification co-capture. While 1, the hook pushes a still-being-measured
|
// Host -> hook: format-verification co-capture. While 1, the hook pushes a still-being-measured
|
||||||
// (guessed) stream's raw pre-mix bytes into the ring WITHOUT silencing the game, so the host can
|
// (guessed) stream's raw pre-mix bytes into the ring WITHOUT silencing the game, so the host can
|
||||||
// capture both the hook (pre-mix) and a parallel process-loopback (post-mix) of the same audio
|
// capture both the hook (pre-mix) and a parallel process-loopback (post-mix) of the same audio
|
||||||
// and cross-correlate them to recover the true sample rate (and, in step b, channels/bit-depth)
|
// and cross-correlate them to recover the true sample rate / channels / bit-depth from ground
|
||||||
// from ground truth instead of guessing. Inert (0) by default -- normal capture is unaffected,
|
// truth instead of guessing (see audio_correlate.hpp). Inert (0) by default -- normal capture is
|
||||||
// so it never changes the shipping no-echo path. It's a 4-byte atomic carved out of the header's
|
// unaffected, so it never changes the shipping no-echo path.
|
||||||
// reserved space; the version gate (kAudioRingVersion) rejects any layout that doesn't match.
|
|
||||||
std::atomic<std::uint32_t> verify_capture;
|
std::atomic<std::uint32_t> verify_capture;
|
||||||
|
|
||||||
std::uint8_t reserved[36];
|
std::uint8_t reserved[36];
|
||||||
@@ -275,10 +274,9 @@ inline std::uint32_t audio_ring_poll_op(AudioRingHeader& h, std::uint32_t& last_
|
|||||||
return out.kind;
|
return out.kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the per-pid audio ring name both sides agree on. Stream 0 keeps the bare
|
// Build the per-pid audio ring name both sides agree on. Stream 0 uses the bare
|
||||||
// coop_audio_<pid> name (backward compatible / the single-stream case); additional
|
// coop_audio_<pid> name; additional streams append _<index> (coop_audio_<pid>_1,
|
||||||
// streams append _<index> (coop_audio_<pid>_1, _2, ...). The host captures every
|
// _2, ...). The host captures every render stream into its own ring and mixes them.
|
||||||
// render stream into its own ring and mixes them.
|
|
||||||
inline std::wstring audio_ring_name(unsigned long target_pid, unsigned index = 0)
|
inline std::wstring audio_ring_name(unsigned long target_pid, unsigned index = 0)
|
||||||
{
|
{
|
||||||
std::wstring name = std::wstring(kAudioRingPrefix) + std::to_wstring(target_pid);
|
std::wstring name = std::wstring(kAudioRingPrefix) + std::to_wstring(target_pid);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
// ever falls a whole ring behind (fine for diagnostics). POD + version-locked.
|
// ever falls a whole ring behind (fine for diagnostics). POD + version-locked.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -94,15 +95,16 @@ inline void log_ring_push(LogRing& r, std::uint32_t pid, std::uint32_t level, st
|
|||||||
LogRecord& rec = log_ring_records(&r)[idx % r.capacity];
|
LogRecord& rec = log_ring_records(&r)[idx % r.capacity];
|
||||||
// Seqlock write. Mark the slot in-progress (seq 0) and fence BEFORE touching the record, so a
|
// Seqlock write. Mark the slot in-progress (seq 0) and fence BEFORE touching the record, so a
|
||||||
// consumer still reading the slot's previous occupant sees seq change and bails instead of reading
|
// consumer still reading the slot's previous occupant sees seq change and bails instead of reading
|
||||||
// half-overwritten text; publish the new generation only after the text is fully written. Without
|
// half-overwritten text; publish the new generation only after the text is fully written. A single
|
||||||
// this the consumer's single seq check passed before the read, so an overwrite mid-read tore it.
|
// seq check before the consumer's copy would miss an overwrite that starts mid-read.
|
||||||
rec.seq.store(0, std::memory_order_relaxed);
|
rec.seq.store(0, std::memory_order_relaxed);
|
||||||
std::atomic_thread_fence(std::memory_order_release);
|
std::atomic_thread_fence(std::memory_order_release);
|
||||||
rec.pid = pid;
|
rec.pid = pid;
|
||||||
rec.level = level;
|
rec.level = level;
|
||||||
rec.millis = millis;
|
rec.millis = millis;
|
||||||
std::strncpy(rec.text, text, kLogMsgLen - 1);
|
const std::size_t len = std::min<std::size_t>(std::strlen(text), kLogMsgLen - 1);
|
||||||
rec.text[kLogMsgLen - 1] = '\0';
|
std::memcpy(rec.text, text, len);
|
||||||
|
rec.text[len] = '\0';
|
||||||
std::atomic_thread_fence(std::memory_order_release);
|
std::atomic_thread_fence(std::memory_order_release);
|
||||||
rec.seq.store(idx + 1, std::memory_order_relaxed); // publish: generation idx is ready
|
rec.seq.store(idx + 1, std::memory_order_relaxed); // publish: generation idx is ready
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
//
|
//
|
||||||
// Header-only, no Windows / no audio-device dependency, so it is unit-tested with
|
// Header-only, no Windows / no audio-device dependency, so it is unit-tested with
|
||||||
// synthesized adversarial signals (tests/tone_analysis_test.cpp) and reused by the
|
// synthesized adversarial signals (tests/tone_analysis_test.cpp) and reused by the
|
||||||
// coop_audio_validate tool. See README "Lessons learned" / the audio notes.
|
// coop_audio_validate tool.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|||||||
Reference in New Issue
Block a user