feat(clients): wire RNNoise mic noise reduction into Windows, macOS, and iOS

Expose the existing send-side vc_set_input_noise_reduction C ABI (MIC-only,
mono, LOCAL — denoises captured mic PCM before input gain and VAD/PTT gate)
as a persisted global toggle in each client's audio settings, applied live
and re-applied on Join Voice. Mirrors the existing mic-gain wiring pattern.

- Shared Swift (VoiceCatCore): add setInputNoiseReduction(_:) wrapper
- Windows: P/Invoke + SetInputNoiseReduction wrapper, MicNoiseReduction in
  VoiceSettings, new checkbox in AudioSettingsForm (layout shifted +28px),
  apply on Join Voice; also fix stale 'planned - currently passthrough'
  label on the receive-side per-user NR checkbox (RNNoise now backs it)
- macOS: inputNoiseReduction state + UserDefaults in MainWindowController,
  NR checkbox + nrChanged action in SettingsWindowController
- iOS: inputNoiseReduction in VoiceState + setter + restore in SessionState,
  NR Toggle in SettingsView Voice section

Aux/screen are out of scope by design (core's NR guards kind == MIC). Apple
builds require a rebuilt VoiceCatCore.xcframework with VOICECAT_HAS_NS.
This commit is contained in:
2026-06-23 14:11:18 +02:00
parent bad9c7533a
commit 2e0e0caccb
11 changed files with 110 additions and 12 deletions

View File

@@ -83,6 +83,9 @@ internal static partial class NativeMethods
[LibraryImport(LibName)]
internal static partial VcResult vc_set_input_gain(nint c, float gain);
[LibraryImport(LibName)]
internal static partial VcResult vc_set_input_noise_reduction(nint c, int enable);
[LibraryImport(LibName)]
internal static partial VcResult vc_set_remote_stream(nint c, uint userId, uint streamId,
float gain, int muted, int noiseReduction);

View File

@@ -232,6 +232,13 @@ public sealed class VoiceCatClient : IDisposable
public VcResult SetInputGain(float gain) =>
NativeMethods.vc_set_input_gain(_handle.DangerousGetHandle(), gain < 0f ? 0f : gain);
/// <summary>Send-side microphone noise suppression (RNNoise). Denoises captured MIC PCM before
/// the input gain and VAD/PTT gate, so everyone hears the cleaned signal. MIC stream only,
/// mono only; always LOCAL — no protocol traffic. Independent of per-listener receive-side
/// NR in <see cref="SetRemoteStream"/>.</summary>
public VcResult SetInputNoiseReduction(bool enable) =>
NativeMethods.vc_set_input_noise_reduction(_handle.DangerousGetHandle(), enable ? 1 : 0);
public VcResult SetRemoteStream(uint userId, uint streamId, float gain, bool muted, bool noiseReduction) =>
NativeMethods.vc_set_remote_stream(_handle.DangerousGetHandle(), userId, streamId, gain,
muted ? 1 : 0, noiseReduction ? 1 : 0);