TASK 4 audio follow-up: game audio bar + mic status dot + always-on capture — the footer's second audio control (desktop/game, a mirror of the mic bar: meter + mute + volume) appears only while a full-screen game is producing sound (IGameAudioDetector seam + GameAudioHysteresis: show ~500ms of fullscreen+sound, hide ~1s after leaving fullscreen, silence never hides an active bar; VM polls on a 250ms timer); capture now runs for the app's lifetime so both meters preview live (started at startup via StartMicCaptureAsync, disposed in Shutdown — no longer go-live driven); MIC label is a button with a status dot (Models/MicStatus: green via the source Started event, yellow = mic problem, red = no device); PickMicrophone swaps the live device immediately via AudioMixer.RestartMic; fixed a latent ?.Invoke(meter.Push(...)) short-circuit that skipped the meter update when nothing subscribed — 167 tests passing, 0 warnings
This commit is contained in:
@@ -2,9 +2,10 @@ namespace ytLive.Services.Audio;
|
||||
|
||||
/// <summary>
|
||||
/// A live audio capture source (TASK 4 ship step 4 seam): produces PCM float
|
||||
/// chunks, runs only while live. The default implementations wrap NAudio's
|
||||
/// WASAPI capture (mic) / loopback (desktop/game); the mixer and the tests
|
||||
/// consume this interface, never NAudio directly.
|
||||
/// chunks. The default implementations wrap NAudio's WASAPI capture (mic) /
|
||||
/// loopback (desktop/game); the mixer and the tests consume this interface,
|
||||
/// never NAudio directly. Capture now runs for the app's lifetime so the
|
||||
/// footer meters stay live in preview — the mixer owns start/stop.
|
||||
/// </summary>
|
||||
public interface IAudioSource : IDisposable
|
||||
{
|
||||
@@ -14,6 +15,10 @@ public interface IAudioSource : IDisposable
|
||||
/// <summary>Stops capturing; a later Start begins a fresh session.</summary>
|
||||
void Stop();
|
||||
|
||||
/// <summary>Raises once capture is live (right after recording starts).
|
||||
/// Never raised when Start fails — <see cref="Failed"/> fires instead.</summary>
|
||||
event Action? Started;
|
||||
|
||||
/// <summary>Raises each captured chunk (interleaved PCM float, -1..1).</summary>
|
||||
event Action<AudioSample>? SampleReady;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user